Reseller System¶
The reseller system enables multi-level affiliate management with credit-based line provisioning. Resellers create and manage IPTV lines, MAG devices, and Enigma2 devices within their allocated credits and permissions.
Overview¶
Admin
└── assigns credits + group permissions
└── Reseller
├── creates IPTV lines (costs credits)
├── creates MAG devices (costs credits)
├── creates Enigma2 devices (costs credits)
└── creates sub-resellers (costs credits)
└── sub-reseller has own lines + credits
Core business logic is in src/Domain/User/ResellerAPI.php. Web controllers are under src/Public/Controllers/Reseller/. REST API is in src/Public/Controllers/Api/ResellerRestApiController.php.
Credit System¶
Credits are the currency for all reseller operations. Each action has a cost, and the reseller's balance must cover it.
Credit costs¶
| Action | Cost source |
|---|---|
| Create line (official) | package.official_credits |
| Create line (trial) | package.trial_credits |
| Create MAG device | same as line |
| Create Enigma2 device | same as line |
| Create sub-reseller | permissions.create_sub_resellers_price |
Override pricing¶
Resellers can have custom per-package pricing via override_packages JSON on their user record:
$rOverride = json_decode($rUserInfo['override_packages'], true);
if (isset($rOverride[$rPackage['id']]['official_credits'])) {
$rCost = intval($rOverride[$rPackage['id']]['official_credits']);
}
Credit transfer¶
Resellers can transfer credits to their direct reports via the adjust_credits API action. Both balances must remain >= 0.
Logging¶
All credit operations are recorded in users_logs:
| Field | Description |
|---|---|
owner |
reseller user ID |
type |
line, mag, enigma, user |
action |
new, extend, edit, adjust_credits |
cost |
credits spent |
credits_after |
balance after operation |
package_id |
package used |
date |
timestamp |
Line Management¶
Lines are IPTV user subscriptions. Types:
| Type | Flags |
|---|---|
| Standard IPTV line | is_mag=0, is_e2=0 |
| MAG device | is_mag=1 |
| Enigma2 device | is_e2=1 |
Creation process¶
- Validate package accessibility (must be in reseller's group permissions).
- Verify
credits >= cost. - Generate username/password if allowed by permissions.
- Apply package:
exp_date,max_connections,bouquets,allowed_outputs. - Set restrictions:
allowed_ips(JSON),allowed_ua,bypass_ua,is_isplock. - Insert into
linestable viaREPLACE INTO. - Sync device entries (
mag_devicesorenigma2_devices). - Broadcast signal event to streaming servers.
- Deduct credits and log transaction.
Bouquet assignment¶
Each package specifies available bouquets via bouquets JSON array.
If allow_change_bouquets permission is enabled, the reseller can select a subset of the package bouquets. Otherwise all package bouquets are auto-assigned.
Device Management¶
MAG devices¶
Managed by MagService (src/Domain/Device/MagService.php).
Lock fields: ver, device_id2, device_id, hw_version, image_version, stb_type, sn.
Enigma2 devices¶
Managed by EnigmaService (src/Domain/Device/EnigmaService.php).
Lock fields: token, lversion, cpu, enigma_version, modem_mac, local_ip.
Both device types support lock_device (hardware binding), is_isplock (ISP binding), and forced_country.
Sub-Reseller Hierarchy¶
Resellers can create sub-resellers (if create_sub_resellers permission is granted):
- Sub-resellers are linked via
owner_idfield. - Multi-level: a sub-reseller can create their own sub-resellers.
- Each creation costs
create_sub_resellers_pricecredits. - Assigned
member_group_idmust be in the parent'ssubresellerspermission array.
Ownership queries:
Authorization::check('user', $rID) // checks reseller hierarchy
Authorization::check('line', $rID) // checks if reseller's reports own the line
Methods:
UserRepository::getResellers($rOwner, $rIncludeSelf)
UserRepository::getDirectReports()
AuthRepository::getGroupPermissions() // builds all_reports recursively
Permissions¶
Permissions come from the users_groups table, loaded via AuthRepository::getPermissions().
Key permission fields¶
| Permission | Type | Description |
|---|---|---|
is_reseller |
bool |
user is a reseller |
create_line |
bool |
can create IPTV lines |
create_mag |
bool |
can create MAG devices |
create_enigma |
bool |
can create Enigma2 devices |
create_sub_resellers |
bool |
can create sub-resellers |
create_sub_resellers_price |
int |
credit cost per sub-reseller |
allow_change_bouquets |
bool |
can select bouquet subset |
allow_change_username |
bool |
can set custom username |
allow_change_password |
bool |
can set custom password |
allow_restrictions |
bool |
can set IP/UA restrictions |
can_view_vod |
bool |
can view VOD content |
reseller_client_connection_logs |
bool |
can view connection logs |
minimum_username_length |
int |
minimum username length |
minimum_password_length |
int |
minimum password length |
Page-level checks¶
PageAuthorization::checkResellerPermissions() maps pages to permissions:
| Pages | Required permission |
|---|---|
user, users |
create_sub_resellers |
line, lines |
create_line |
mag, mags |
create_mag |
enigma, enigmas |
create_enigma |
epg_view, streams, movies |
can_view_vod |
live_connections, line_activity |
reseller_client_connection_logs |
Boundaries¶
What resellers cannot do:
- Access lines/users outside their hierarchy.
- Create or modify packages.
- Access admin-only settings.
- Exceed their credit balance.
- Bypass package group restrictions.
REST API¶
File: src/Public/Controllers/Api/ResellerRestApiController.php
Authentication via API key. Actions:
| Action | Description |
|---|---|
user_info |
reseller account info |
packages |
available packages |
get_lines / get_mags / get_enigmas |
list resources |
create_line / edit_line / delete_line |
line CRUD |
enable_line / disable_line |
toggle line status |
create_mag / edit_mag / delete_mag |
MAG CRUD |
create_enigma / edit_enigma / delete_enigma |
Enigma CRUD |
convert_mag / convert_enigma |
convert device type |
get_users / get_user |
list/view sub-resellers |
create_user / edit_user / delete_user |
sub-reseller CRUD |
enable_user / disable_user |
toggle sub-reseller status |
adjust_credits |
transfer credits to sub-reseller |
activity_logs / live_connections |
connection data |
user_logs |
sub-reseller activity logs |
The ResellerAPIWrapper class validates the API key, initializes a session via ResellerAPI, and returns filtered JSON responses.
Session and Bootstrap¶
Session¶
File: src/Infrastructure/Bootstrap/reseller_session.php
- 60-minute timeout with last activity tracking.
- IP change detection (if
ip_logoutsetting enabled). - Session keys:
reseller(user ID),rip,rcode,rverify,rlast_activity.
Functions bootstrap¶
File: src/Infrastructure/Bootstrap/reseller_functions.php
- Loads database and utilities.
- Initializes
$rUserInfoand$rPermissions. - Validates session integrity (username/password hash verification).
- Sets timezone and language preferences.
Routes¶
File: src/Public/routes/reseller.php
Key routes:
GET /dashboard → ResellerDashboardController
GET /edit_profile → ResellerEditProfileController
POST /post → ResellerPostController (form handler)
GET /api, POST /api → ResellerApiController
GET /table, POST /table → ResellerTableController
GET /lines → ResellerLinesController
GET /line → ResellerLineController
GET /mags → ResellerMagsController
GET /mag → ResellerMagController
GET /enigmas → ResellerEnigmasController
GET /enigma → ResellerEnigmaController
GET /users → ResellerUsersController
GET /user → ResellerUserController
GET /user_logs → ResellerUserLogsController
GET /live_connections → ResellerLiveConnectionsController
GET /line_activity → ResellerLineActivityController
GET /tickets → ResellerTicketsController
Related files¶
| File | Purpose |
|---|---|
src/Domain/User/ResellerAPI.php |
core business logic |
src/Public/Controllers/Api/ResellerRestApiController.php |
REST API |
src/Public/Controllers/Reseller/*.php |
web controllers |
src/Public/routes/reseller.php |
URL routing |
src/Public/Views/reseller/*.php |
view templates |
src/Infrastructure/ResellerApiDispatcher.php |
AJAX action routing |
src/Infrastructure/ResellerTableRenderer.php |
DataTables rendering |
src/Infrastructure/Bootstrap/reseller_session.php |
session management |
src/Infrastructure/Bootstrap/reseller_functions.php |
initialization |
src/Core/Auth/Authorization.php |
ownership checks |
src/Core/Auth/PageAuthorization.php |
page-level gating |