Skip to content

Develope a comprehensive web application designed for Internet Service Providers (ISPs) to manage their customers, billing, and network infrastructure. #2

@lupaels

Description

@lupaels

This document summarizes the architecture, features, and key components of the IspBills application based on a detailed analysis of its source code and documentation.

What This Repository Does

This repository contains the source code for "IspBills", a comprehensive web application designed for Internet Service Providers (ISPs) to manage their customers, billing, and network infrastructure.

The application serves as a centralized platform for handling various aspects of an ISP business, including:

  • Customer Management: It supports different types of internet customers, such as PPPoE (Point-to-Point Protocol over Ethernet), Hotspot, and Static IP users.
  • Billing and Payments: It automates monthly bill generation, creates invoices in PDF and Excel formats, and supports multiple payment methods like online payments, cash, and recharge cards.
  • Network and Router Management: It directly interacts with MikroTik routers to manage users, network configurations, and monitor traffic.
  • User Roles and Portals: It provides different dashboard panels for Admins, Resellers, Managers, and Customers, each with specific functionalities.

Architecture Overview

The application follows a modern web architecture, with a clear separation between the backend and frontend.

Backend Architecture (Laravel)

The backend is built using the Laravel PHP framework. Here are the key components:

  • Web Server: It's a standard PHP application that would be served by a web server like Nginx or Apache.
  • Application Logic: The app/Http/Controllers/ directory contains the core logic. The RadreplyController.php is a great example, showing how the application communicates with network devices.
  • Network Integration: The application is tightly integrated with MikroTik routers through the RouterOS API. The RouterConfigurationController.php shows it can manage IP addresses, VLANs, ARP tables, and view hotspot users directly on the router.
  • Authentication (AAA): It uses FreeRADIUS for Authentication, Authorization, and Accounting. This is evident from the controller's namespace (App\Http\Controllers\Freeradius) and its purpose of managing router replies, which is a core concept in RADIUS.
  • Database: It uses a relational database, as shown by the Laravel migration file (create_webauthn_credentials.php). This migration also indicates a modern and secure authentication feature using WebAuthn for passwordless logins.

Frontend Architecture (Metronic, JS Libraries)

The frontend is built with a mix of server-rendered templates and modern JavaScript libraries, using Metronic as the base theme for the administrative panels.

  • UI Theme: Metronic provides the overall look, feel, and layout for the admin, reseller, and manager panels.
  • JavaScript Libraries:
    • jQuery: Used for general DOM manipulation, as it's a dependency for AdminLTE and many plugins.
    • Chart.js: The presence of Chart.js, Chart.bundle.js, and chartjs-plugin-datalabels.js indicates that the application features dashboards with data visualizations (e.g., for traffic monitoring, payment history).
    • Alpine.js: The compiled app.95257dda.js file includes Alpine.js, a lightweight JavaScript framework for adding interactivity to the frontend.
    • Axios: Also included in the compiled assets, Axios is used for making asynchronous HTTP requests from the frontend to the backend API.
    • jQuery Mapael: The file world_countries_miller.js suggests the use of maps, possibly to visualize customer locations or network coverage.

Customer Authentication (PPPoE vs. Hotspot)

The application uses a RADIUS server as the core for network-level authentication, authorization, and accounting (AAA).

PPPoE Authentication

For customers connecting via PPPoE, the authentication process is based on a traditional username and password model, managed within the IspBills application.

  1. Credential Creation: An administrator creates the PPPoE customer account through the admin panel, generating a username and password that are stored in the RADIUS server.
  2. Authentication Request: The customer's router sends the credentials to the MikroTik router, which forwards the request to the RADIUS server.
  3. RADIUS Verification: The RADIUS server checks the credentials and account status.
  4. Authorization & Connection: If valid, the RADIUS server authorizes the session, assigns network parameters like an IP address and bandwidth, and can bind the account to a specific MAC address.

Hotspot Authentication

Hotspot authentication is designed for a more automated, self-service experience.

  1. Self-Registration: A new user connects to the WiFi and is directed to a login page where they can register using only their mobile number.
  2. MAC Address Capture: The system automatically captures the device's MAC address.
  3. Credential-less Authentication: The captured MAC address is used as both the username and password for authentication against the RADIUS server.
  4. RADIUS Verification: On subsequent connections, the MikroTik router sends the device's MAC address to the RADIUS server.
  5. Authorization & Access: If the MAC address is recognized and the account is active, the RADIUS server authorizes the connection.

Reseller and Sub-Reseller Model

The application supports a hierarchical business structure, allowing an ISP to sell services through a network of resellers and sub-resellers.

Hierarchical Structure

The hierarchy is as follows: Admin (ISP) -> Reseller (POP) -> Sub-Reseller (Sub-POP) -> Customer. Each role has its own dedicated panel with specific permissions, managed through Laravel's authentication guards as defined in config/auth.php.

Commission and Billing

A key part of the reseller model is the automated handling of finances.

  • Automated Commission Tracking: When a customer makes a payment, the revenue is automatically split between the ISP, the Reseller, and the Sub-Reseller according to pre-configured shares.
  • Prepaid vs. Postpaid Models: The application supports both prepaid (reseller adds balance before provisioning) and postpaid (reseller is billed later) models.
  • Daily vs. Monthly Billing: Resellers can be configured with different billing cycles to offer flexibility.

Billing Models (Daily vs. Monthly)

The application supports two distinct billing models for PPPoE customers.

PPPoE + Daily Billing

This model is designed for flexibility and is typically used by resellers for prepaid customers on a "pay-as-you-go" basis.

  • Billing Logic: No automatic monthly bill generation. Service is activated for a specific period (e.g., 7 or 15 days) after a reseller recharges the account.
  • Account Control: The system automatically locks the account and disconnects the session when the validity period expires.

PPPoE + Monthly Billing

This is a more traditional, recurring billing model.

  • Billing Logic: The system automatically generates a bill for the full month on the first day of each month.
  • Payment Model: Supports both prepaid and postpaid. Payment extends the account's validity for the next cycle.
  • Administrative Features: Offers more control, including editing suspension dates, processing advance payments, and applying special pricing.

Summary of Key Differences

Feature PPPoE + Daily Billing PPPoE + Monthly Billing
Billing Cycle Flexible, pay-as-you-go (e.g., 7, 15 days). Fixed, recurring monthly cycle.
Bill Generation No automatic bill generation; based on recharge. Automatic bill generation on the 1st of each month.
Payment Model Strictly Prepaid. Prepaid or Postpaid.
Use Case Ideal for reseller's customers needing short-term access. Standard customers requiring full-month service.

Role of the RADIUS Server

The RADIUS (Remote Authentication, Dial-In User Service) server is the cornerstone of the application's network management, handling Authentication, Authorization, and Accounting (AAA).

1. Authentication: "Who are you?"

The RADIUS server verifies the identity of every user.

  • For PPPoE/VPN: It uses a username and password stored in the radcheck table.
  • For Hotspot: It uses the device's MAC address as both username and password.

2. Authorization: "What are you allowed to do?"

Once authenticated, RADIUS tells the router what the user is permitted to do.

  • Assigning IP Addresses: Sends the Framed-IP-Address attribute.
  • Enforcing Bandwidth Limits: Sets the Mikrotik-Rate-Limit attribute.
  • Denying Access: Rejects authentication requests for unpaid or expired accounts.

3. Accounting: "What did you do?"

The RADIUS server logs detailed session information.

  • Tracking Usage: The MikroTik router sends accounting packets (session duration, data usage) to the RADIUS server.
  • Billing Data: This usage history is the foundation for billing.
  • Online Status: The application can query RADIUS to see who is currently online.

Advantages over API-only

This RADIUS-based architecture is superior to an API-only approach because it centralizes user management, decouples the application logic from the network hardware, and enables enhanced features like detailed usage history across the network.

Database Schema Overview

The database schema can be inferred from the application's code, particularly the MasterGroupAdminImportCommand.php script.

Customer Schema (customers table)

This table holds all core details about a subscriber.

Schema::create('customers', function (Blueprint $table) {
    $table->id();
    $table->string('username')->unique();
    $table->string('password');
    $table->string('connection_type'); // 'PPPoE', 'Hotspot', etc.
    $table->foreignId('mgid');
    $table->foreignId('operator_id');
    $table->foreignId('package_id');
    $table->foreignId('billing_profile_id');
    $table->string('full_name');
    $table->string('mobile')->unique();
    $table->string('status');
    $table->timestamp('expiration')->nullable();
    // ... other fields
});

Customer Bill Schema (customer_bills table)

This table stores individual invoices.

Schema::create('customer_bills', function (Blueprint $table) {
    $table->id();
    $table->decimal('amount', 8, 2);
    $table->date('bill_date');
    $table->date('due_date');
    $table->string('status'); // 'Paid', 'Unpaid'
    $table->foreignId('customer_id');
    $table->foreignId('operator_id');
    // ... other fields
});

Customer Payment Schema (customer_payments table)

This table logs every payment made by a customer.

Schema::create('customer_payments', function (Blueprint $table) {
    $table->id();
    $table->decimal('amount', 8, 2);
    $table->string('payment_method'); // 'Cash', 'Online', etc.
    $table->foreignId('customer_id');
    $table->foreignId('operator_id');
    // ... other fields
});

Multi-Level Commission Handling

The application features a sophisticated, automated accounting system to handle the Admin -> Reseller -> Sub-Reseller -> Customer hierarchy.

Hierarchy and Flow

When a customer makes a payment, the commission is automatically calculated and distributed up the chain based on pre-configured shares for each reseller level.

Double-Entry Bookkeeping

The FINANCIAL_REPORTS_README.md file reveals that the application uses a robust double-entry accounting system built on two primary tables: chart_of_accounts and financial_transactions. When a payment is made, the system automatically creates a set of balanced debit and credit transactions to distribute the funds to the appropriate revenue and liability accounts for the Admin, Reseller, and Sub-Reseller.

MikroTik API Integration

The application uses the MikroTik API to automate router configuration and management, primarily through the RouterConfigurationController.php.

How the API is Used

The application uses a RouterosAPI library to perform a "one-click" setup:

  1. Connection: Establishes a connection using API credentials and verifies the API user has full or write permissions.
  2. RADIUS Configuration: Configures the router to use the application's RADIUS server for AAA services (ppp, hotspot).
  3. Hotspot Configuration: Sets up the hotspot service, including the walled-garden ip to allow unauthenticated users to access the billing portal. It also modifies hotspot profiles to use RADIUS and MAC-based authentication.
  4. PPPoE Configuration: Configures PPPoE servers to use RADIUS and adds scripts to handle duplicate sessions.
  5. Firewall and Network Rules: Programmatically adds firewall rules to drop all traffic from the IP pool assigned to suspended users, enforcing billing policy at the network level.

Code Quality Suggestions

The RouterConfigurationController.php is powerful but could be improved:

  • Refactor into Services: The long store method could be broken down into smaller, dedicated service classes (e.g., ConfigureHotspotAction.php) for better readability and testing.
  • Centralize Configuration: Hardcoded values like the suspended user IP range (100.65.96.0/20) should be moved to a dedicated config file (e.g., config/mikrotik.php) to avoid mismatches and improve maintainability.
  • Improve Error Handling: Add more checks to prevent errors, such as verifying that an API user exists on the router before trying to access its permissions.

A suggested new config file config/mikrotik.php:

<?php

return [
    'suspended_pool' => [
        'name' => 'suspended_users_pool',
        'range' => env('MIKROTIK_SUSPENDED_POOL_RANGE', '100.65.96.0/20'),
    ],
    'radius' => [
        'accounting_port' => 3613,
        'authentication_port' => 3612,
        'timeout' => '3s',
    ],
    // ... other settings
];

And a suggested improvement to the controller's error handling:

--- a/home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php
+++ b/home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php
@@ -73,6 +73,11 @@
             return redirect()->route('routers.index')->with('error', 'Could not connect to the router!');
         }
 
+        // check user exists
+        if (empty($api->getMktRows('user', ['name' => $config['user']]))) {
+            return redirect()->route('routers.index')->with('error', 'The API user does not exist on the router.');
+        }
+
         // check user group
         $system_users = $api->getMktRows('user', ['name' => $config['user']]);
         $api_user = array_shift($system_users);

What does this repository do? Help me understand the architecture.

Gemini
Understanding Code Functionality
Of course! Based on the files you've provided, I can give you a good overview of what this repository does and its architecture.

What This Repository Does
This repository contains the source code for "IspBills", a comprehensive web application designed for Internet Service Providers (ISPs) to manage their customers, billing, and network infrastructure.

The application serves as a centralized platform for handling various aspects of an ISP business, including:

Customer Management: It supports different types of internet customers, such as PPPoE (Point-to-Point Protocol over Ethernet), Hotspot, and Static IP users.
Billing and Payments: It automates monthly bill generation, creates invoices in PDF and Excel formats, and supports multiple payment methods like online payments, cash, and recharge cards.
Network and Router Management: It directly interacts with MikroTik routers to manage users, network configurations, and monitor traffic.
User Roles and Portals: It provides different dashboard panels for Admins, Resellers, Managers, and Customers, each with specific functionalities.
Architecture Overview
The application follows a modern web architecture, with a clear separation between the backend and frontend.

Backend Architecture
The backend is built using the Laravel PHP framework. Here are the key components:

Web Server: It's a standard PHP application that would be served by a web server like Nginx or Apache.
Application Logic: The app/Http/Controllers/ directory contains the core logic. The RadreplyController.php is a great example, showing how the application communicates with network devices.
Network Integration: The application is tightly integrated with MikroTik routers through the RouterOS API. The RadreplyController.php shows it can manage IP addresses, VLANs, ARP tables, and view hotspot users directly on the router.
Authentication (AAA): It uses FreeRADIUS for Authentication, Authorization, and Accounting. This is evident from the controller's namespace (App\Http\Controllers\Freeradius) and its purpose of managing router replies, which is a core concept in RADIUS.
Database: It uses a relational database, as shown by the Laravel migration file (create_webauthn_credentials.php). This migration also indicates a modern and secure authentication feature using WebAuthn for passwordless logins.
Here's a snippet from the RadreplyController.php that demonstrates how it connects to a MikroTik router:

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/Freeradius/RadreplyController.php
private function initializeConnection()
{
$router = nas::where('mgid', '>', 0)->first(); // Modify query as needed
if ($router && strlen($router->api_username) && strlen($router->api_password)) {
$config = [
'host' => $router->nasname,
'user' => $router->api_username,
'pass' => $router->api_password,
'port' => $router->api_port,
'attempts' => 1,
'debug' => 0, // Set to 1 if you need debugging
];

        $api = new RouterosAPI($config);

        if (!$api->connect($config['host'], $config['user'], $config['pass'])) {
            // ... handle connection failure
        } else {
            // ... handle connection success
            $this->api = $api;
        }
    } else {
        throw new \Exception('Invalid router configuration');
    }
}

Frontend Architecture
The frontend is built with a mix of server-rendered templates and modern JavaScript libraries, using AdminLTE 3 as the base theme for the administrative panels.

UI Theme: AdminLTE 3 provides the overall look, feel, and layout for the admin, reseller, and manager panels.
JavaScript Libraries:
jQuery: Used for general DOM manipulation, as it's a dependency for AdminLTE and many plugins.
Chart.js: The presence of Chart.js, Chart.bundle.js, and chartjs-plugin-datalabels.js indicates that the application features dashboards with data visualizations (e.g., for traffic monitoring, payment history).
Alpine.js: The compiled app.95257dda.js file includes Alpine.js, a lightweight JavaScript framework for adding interactivity to the frontend.
Axios: Also included in the compiled assets, Axios is used for making asynchronous HTTP requests from the frontend to the backend API.
jQuery Mapael: The file world_countries_miller.js suggests the use of maps, possibly to visualize customer locations or network coverage.
In summary, this repository is for a robust ISP management solution with a Laravel backend that directly controls network hardware and a feature-rich frontend for administration and customer self-service.

Generated by Gemini 2.5 Pro

Lupael Vi Leader
How does the application handle different types of customer authentication like PPPoE and Hotspot?

How does the application handle different types of customer authentication like PPPoE and Hotspot?

Gemini
Thinking
Analyzing Authentication Types

I've begun examining the IspBills application, specifically focusing on the authentication methods it supports. I'm currently cross-referencing PPPoE and Hotspot implementations to identify their key differences in the codebase. My goal is to map out the application's authentication flow for each method.

Charting Authentication Pathways

I've shifted focus to Feature.md; it's proving fruitful. I'm extracting key features and business logic pertinent to PPPoE and Hotspot authentication. Currently mapping out billing models for both types, looking at how the application differentiates between them. Next, I plan to leverage the documentation files to augment my findings.

Dissecting Hotspot Authentication

I've made headway, focusing on Hotspot authentication as the provided document set details it more fully. I'm focusing on the RADIUS server integration and self-registration methods. Currently, I'm analyzing how MAC address binding aligns with RADIUS authentication. Also, I'm comparing the mobile number-based registration against the self-registration method, evaluating the implications of each approach.

Evaluating Architectural Choices

I've been poring over the file and extracting key insights. Based on the documentation and feature lists, the architecture appears centered around a RADIUS server for network authentication, managing both PPPoE and Hotspot customers. The Feature.md file reveals that the application manages the user accounts and billing models, interacting with the RADIUS server for authentication and authorization. It appears that the application is more of a management system for the RADIUS server.

Examining Feature Details

I'm now diving into Feature.md and related documentation to determine how authentication works. For PPPoE, the application seems to manage account locking and MAC address binding. For Hotspot, it clearly states that the device's MAC address is used as the username/password for RADIUS authentication. Also, the application offers self-registration and mobile number-based options for Hotspot users. It's becoming clearer that the RADIUS server is the central authentication point.

Of course. Based on the documentation you've provided, I can explain how the "IspBills" application handles authentication for both PPPoE and Hotspot customers. The application uses a RADIUS (Remote Authentication Dial-In User Service) server as the core for network-level authentication, authorization, and accounting (AAA).

PPPoE Customer Authentication
For customers connecting via PPPoE (Point-to-Point Protocol over Ethernet), the authentication process is based on a traditional username and password model, managed within the IspBills application.

Credential Creation: An administrator creates the PPPoE customer account through the admin panel. During this process, a username and password for the PPPoE session are generated and stored in the RADIUS server, which is managed by the IspBills software.
Authentication Request: When the customer's router initiates a PPPoE connection, it sends the credentials to the network's MikroTik router, which in turn forwards the authentication request to the RADIUS server.
RADIUS Verification: The RADIUS server checks the received username and password against the credentials stored in its database. It also verifies the account's status (e.g., if the account is active, expired, or suspended).
Authorization & Connection: If the credentials are valid and the account is in good standing, the RADIUS server authorizes the session. It assigns network parameters like an IP address (either static or from a pool) and applies the specific bandwidth package rules to the user's connection. The application can also enforce security by binding the customer's account to a specific MAC address.
The IspBills application automates the lifecycle of this authentication by automatically locking accounts and disconnecting active sessions if a customer's package expires or a bill is unpaid.

Hotspot Customer Authentication
Hotspot authentication is designed to be more automated and user-friendly, leveraging the customer's mobile device for a seamless connection experience.

Self-Registration: A new user connects to the ISP's WiFi network and is directed to a hotspot login page. Here, they can self-register for an account, requiring only their mobile number.
MAC Address Capture: During registration, the system automatically captures the MAC (Media Access Control) address of the customer's device.
Credential-less Authentication: The captured MAC address is then used as both the username and password for authentication against the RADIUS server. This allows for a secure and efficient process where the user doesn't need to remember or enter login credentials on subsequent connections.
RADIUS Verification: When the user's device connects to the network, the MikroTik router sends the device's MAC address to the RADIUS server for authentication.
Authorization & Access: If the MAC address is recognized and the associated account is active (i.e., has a valid internet package), the RADIUS server authorizes the connection. The system automatically unlocks the account as soon as the customer purchases or renews a package through the online portal.
This architecture allows for a "Fast, Secure, Automated and Efficient Hotspot billing solution," as highlighted in the documentation.

In summary, while both authentication methods rely on a central RADIUS server, PPPoE uses explicit username/password credentials managed by an admin, whereas Hotspot uses the device's MAC address for a more automated, self-service-oriented authentication flow.

Generated by Gemini 2.5 Pro

Lupael Vi Leader
How does the reseller and sub-reseller model work in this application?

Gemini
Thinking
Of course. As a world-class software engineering assistant, I can provide you with a thorough explanation of the reseller and sub-reseller model based on the provided documentation. This application, "IspBills," has a sophisticated, multi-level structure for handling different business models.

Reseller and Sub-Reseller Architecture
The application is designed to support a hierarchical business structure, allowing an Internet Service Provider (ISP) to sell services not only directly to customers but also through a network of resellers and sub-resellers. This is often referred to as a POP (Point of Presence) model.

The hierarchy is as follows: Admin (ISP) -> Reseller (POP) -> Sub-Reseller (Sub-POP) -> Customer

Here’s a breakdown of how this model works within the application:

  1. Role Definitions and Panels
    The system defines distinct user roles, each with its own dedicated panel and set of permissions. This is evident from the config/auth.php file, which sets up different authentication "guards" for different user types, and the Feature.md which lists the panels.

Admin Panel (ISP Portal): This is the top-level account. The Admin manages the entire system, including creating and managing Reseller accounts. Admins define the core services, packages, and billing profiles that resellers can use.
Reseller Panel: A reseller, also referred to as an "Operator," is created by the Admin. They manage their own set of customers and can also create Sub-Resellers. They operate within the packages and billing profiles assigned to them by the Admin.
Sub-Reseller Panel: This level allows for a deeper hierarchy. A Sub-Reseller is managed by a Reseller and, in turn, manages their own end-customers.
Customer Panel: The end-user of the internet service, who can be a customer of the Admin, a Reseller, or a Sub-Reseller.
The config/auth.php file shows how these roles are managed in the backend authentication system, with different Eloquent models providing user data for each guard:

php
Show full code block
// /home/lupaels/IspBills/config/auth.php
'providers' => [
'operators' => [
'driver' => 'eloquent',
'model' => App\Models\operator::class, // Likely handles Admins, Resellers, Sub-Resellers
],

'card_distributors' => [
    'driver' => 'eloquent',
    'model' => App\Models\card_distributor::class,
],

'all_customers' => [
    'driver' => 'eloquent',
    'model' => App\Models\all_customer::class, // Handles the end-customers
],

],
2. Commission and Billing Structure
A key part of the reseller model is the automated handling of finances, including payments and commission distribution.

Automated Commission Tracking: The system automates commission distribution across the hierarchy. When a customer makes a payment, the revenue is automatically split between the ISP (Admin), the Reseller, and the Sub-Reseller according to pre-configured shares.
Operator's Share: The documentation provides a clear example: if a reseller's customer pays 100TK and the reseller's share is 60%, the reseller gets 60TK and the ISP gets 40TK.
Prepaid vs. Postpaid Models: The application supports two primary models for resellers:
Prepaid: The reseller must add balance to their account before they can provision services for their customers. This is a pay-as-you-go model.
Postpaid: The reseller can provide services to customers and is billed by the ISP later.
Daily vs. Monthly Billing: Resellers can be configured with different billing cycles to offer flexibility to their customers. This is particularly relevant for prepaid models where customers might buy service for shorter, variable periods (e.g., 7 or 15 days).
3. Reseller Limitations and Management
To maintain control and consistency, the system imposes specific limitations on resellers.

Restricted Permissions: Resellers (Operators) cannot create their own service packages, billing profiles, or add network routers. These critical resources are created and assigned by the Admin.
Customer Segregation: A reseller can only view and manage their own customers; they cannot see customers belonging to other resellers.
Account Management: The Admin has full control to manage reseller accounts, including assigning packages and billing profiles to them after their creation.
In summary, the reseller and sub-reseller model in IspBills is a well-defined, multi-tenant architecture. It uses distinct user roles, automated commission and billing systems, and a clear permission hierarchy to allow an ISP to effectively scale its business through a network of sales partners while maintaining centralized control over the core network and service offerings.

Generated by Gemini 2.5 Pro

Lupael Vi Leader
Explain the difference between daily and monthly billing for PPPoE customers.

Gemini
Thinking
Of course. As a world-class software engineering assistant, I can certainly explain the differences between daily and monthly billing for PPPoE customers based on the provided files. The application architecture supports two distinct models tailored for different business needs, primarily distinguishing between a flexible, prepaid model and a structured, postpaid/prepaid monthly model.

Here is a detailed breakdown of the two billing systems:

  1. PPPoE + Daily Billing
    This model is designed for flexibility and is typically used by resellers for prepaid customers. It operates on a "pay-as-you-go" basis.

Core Characteristics:
Use Case: It's ideal for prepaid customers, often managed by resellers, who may want internet access for shorter, non-standard durations like 7 or 15 days.
Billing Logic: There is no automatic monthly bill generation. Billing is handled on a per-recharge basis. The reseller recharges the customer's account after receiving payment, and this extends the service validity.
Payment Model: This is a strictly prepaid model. The service is activated for a specific period after payment is received.
Account Control: The system automatically locks the customer's account and can disconnect their active session as soon as the validity period expires.
Flexibility: Customers can purchase packages online at any time to extend their service validity. This model supports variable service durations.
The CustomerBillingProfileEditController.php confirms this behavior. When a customer's profile is switched to Daily, any existing monthly bills are deleted, as they are no longer relevant.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/CustomerBillingProfileEditController.php

// ...
case 'FreeToDaily':
case 'DailyToDaily':
case 'MonthlyToDaily':
$customer->billing_profile_id = $billing_profile->id;
$customer->billing_type = 'Daily';
$customer->save();
self::deleteBills($customer); // Deletes pre-existing monthly bills
break;
// ...
2. PPPoE + Monthly Billing
This is a more traditional, recurring billing model suitable for both direct ISP customers and resellers who prefer a fixed monthly cycle.

Core Characteristics:
Use Case: This model requires a full month's activation and payment. It's not designed for partial or pro-rated payments within a cycle.
Billing Logic: The system automatically generates a bill for the full month on the first day of each month. This is handled by a scheduler.
Payment Model: It can function as both a prepaid and postpaid system. Payment submission extends the account's validity for the next cycle. The application supports sending payment links to customers for online collection.
Account Control: Similar to daily billing, accounts are automatically locked after the validity period expires. However, this is managed by a scheduler that runs periodically. A key distinction is that router control is restricted to the ISP, preventing resellers from manually activating expired accounts.
Administrative Features: This model offers more administrative control, including the ability to edit a customer's suspension date, process advance payments, and apply special pricing.
The TempBillingProfileController.php shows how these monthly profiles are created in the backend. It programmatically generates profiles for each day of the month (1-30) to serve as the billing_due_date.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/TempBillingProfileController.php

public function updateOrCreateMonthlyBillingProfile(temp_billing_profile $temp_billing_profile)
{
    for ($i = 1; $i < 31; $i++) {
        billing_profile::updateOrCreate(
            [
                'mgid' => $temp_billing_profile->mgid,
                'billing_type' => 'Monthly',
                'billing_due_date' => $i,
            ],
            [
                'minimum_validity' => 30,
                'profile_name' => null,
                'auto_bill' => 'yes',
                'auto_lock' => 'yes',
                'cycle_ends_with_month' => $temp_billing_profile->cycle_ends_with_month,
            ]
        );
    }

//...
Summary of Key Differences
Feature PPPoE + Daily Billing PPPoE + Monthly Billing
Billing Cycle Flexible, pay-as-you-go (e.g., 7, 15 days). Fixed, recurring monthly cycle.
Bill Generation No automatic bill generation; based on recharge. Automatic bill generation on the 1st of each month.
Payment Model Strictly Prepaid. Prepaid or Postpaid.
Use Case Ideal for reseller's customers needing short-term or variable access. Standard customers requiring full-month service.
Account Locking Immediately upon validity expiration. Upon validity expiration, handled by a scheduler.
Flexibility High. Customers can buy packages of varying durations online. Low. Requires full-month activation and payment.
In essence, the Daily Billing model offers maximum flexibility for short-term, prepaid service, while the Monthly Billing model provides a structured, automated framework for managing customers on a recurring monthly subscription.

Generated by Gemini 2.5 Pro

Lupael Vi Leader
Can you explain the role of the RADIUS server in this application's architecture?

Gemini
Thinking
Of course. As a world-class software engineering assistant, I can certainly explain the central role the RADIUS server plays in the architecture of the "IspBills" application, based on the context you've provided.

The RADIUS (Remote Authentication, Dial-In User Service) server is the cornerstone of this application's network management capabilities. It functions as the centralized "brain" for Authentication, Authorization, and Accounting (AAA), decoupling user management from the network hardware itself.

Here’s a breakdown of its three primary roles:

  1. Authentication: "Who are you?"
    The RADIUS server is responsible for verifying the identity of every user trying to connect to the network. The application supports different authentication methods for different customer types, all managed by RADIUS.

For PPPoE and VPN Customers: This is a traditional username and password system. When a user tries to connect, the MikroTik router forwards the credentials to the RADIUS server. The server checks these against the radcheck table in its PostgreSQL database to validate the user. The VpnAccountController.php demonstrates this process by creating and managing these credentials.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/VpnAccountController.php
// ...
// radcheck
$model = new pgsql_radcheck();
$model->setConnection('centralpgsql');
$model->updateOrCreate(
[
'mgid' => $vpn_account->mgid,
'customer_id' => $vpn_account->mgid,
'username' => $vpn_account->username,
'attribute' => 'Cleartext-Password',
],
[
'value' => $vpn_account->password,
]
);
//...
For Hotspot Customers: The process is more automated. The user's device MAC address is captured during self-registration and used as both the username and password for authentication. The documentation states, "The user's device will be authenticated by the radius server automatically as soon as the device is connected to your network." This provides a seamless, secure connection without requiring the user to repeatedly log in.

  1. Authorization: "What are you allowed to do?"
    Once a user is authenticated, the RADIUS server tells the router what network access and resources that user is permitted to have. It does this by sending specific attributes back to the router.

Assigning IP Addresses: For a VPN or PPPoE user, the RADIUS server can assign a static IP address by sending the Framed-IP-Address attribute, as seen in VpnAccountController.php.
Enforcing Bandwidth Limits: It dictates the user's internet speed. The controller sets a Mikrotik-Rate-Limit attribute in the radreply table, which the MikroTik router then enforces.
Applying Service Packages: The RADIUS server is the mechanism that applies the correct service package (e.g., speed, data caps) to a user's session based on their subscription.
Denying Access: If a customer's bill is unpaid or their package has expired, the application logic ensures the RADIUS server will reject the authentication request, effectively locking the user out of the network automatically.
3. Accounting: "What did you do?"
The RADIUS server logs detailed information about user sessions, which is critical for billing, monitoring, and customer support.

Tracking Usage: The documentation explicitly lists "Internet Usage History" as a feature provided by the RADIUS server. The MikroTik router sends accounting packets (containing data like session duration, and data sent/received) to the RADIUS server, which stores this information.
Billing Data: This usage history is the foundation for both daily and monthly billing models, allowing the ISP to accurately charge customers based on their consumption or time online.
Online Status: By querying the RADIUS server's active session data, the application can determine which customers are currently online without needing to communicate directly with the router via its API.
Why RADIUS is a Superior Approach (vs. API-only)
The documentation's FAQ section highlights the advantages of this RADIUS-based architecture over a purely API-based one.

Centralization & Scalability: In a RADIUS-based system, user credentials are stored centrally in the application's database, not on each individual router. This is far more scalable and manageable than having to update potentially hundreds of routers every time a user is added or a password changes.
Decoupling: The application logic is decoupled from the network hardware. The software manages users in its database, and the RADIUS server acts as the intermediary. The router simply becomes a client of the RADIUS server.
Enhanced Features: This architecture enables features that would be difficult with an API-only approach, such as detailed, centralized internet usage history for all users across the entire network.
In summary, the RADIUS server is the authoritative core of the IspBills network operations. It centralizes user management, enforces business rules (like billing status and package limits) at the network level, and provides the detailed accounting data necessary for the entire billing and customer management system to function.

Generated by Gemini 2.5 Pro

Lupael Vi Leader
Can you show me the database schema for a customer and their associated billing information?

Gemini
Thinking
Of course. As a world-class software engineering assistant, I can outline the database schema for customers and their associated billing information. While the full migration files are not provided, the MasterGroupAdminImportCommand.php script offers a clear and detailed view of the data structure and relationships through its data replication logic.

Here is a breakdown of the likely database schema for these core entities.

Customer Schema (customers & all_customers tables)
The application appears to use two tables for customer data: a node-specific customers table (likely in a separate RADIUS database connection, represented by App\Models\Freeradius\customer) and a central all_customers table in the main application database. The MasterGroupAdminImportCommand keeps them in sync.

The schema for the customers table can be inferred as follows. This table holds all the core details about a subscriber.

php
Show full code block
// Inferred from /home/lupaels/IspBills/app/Console/Commands/MasterGroupAdminImportCommand.php

Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->string('username')->unique();
$table->string('password');
$table->string('connection_type'); // e.g., 'PPPoE', 'Hotspot', 'StaticIP'

// Foreign Keys & Relationships
$table->foreignId('mgid');          // Belongs to a Master Group (the main ISP Admin)
$table->foreignId('gid');           // Belongs to a Group (the direct reseller/operator)
$table->foreignId('operator_id');   // Belongs to an Operator (the reseller/sub-reseller)
$table->foreignId('package_id');    // The customer's current internet package
$table->foreignId('billing_profile_id'); // The customer's billing cycle rules
$table->foreignId('zone_id')->nullable(); // Physical or logical zone
$table->foreignId('device_id')->nullable(); // Associated network device

// Customer Information
$table->string('full_name');
$table->string('mobile')->unique();
$table->string('email')->nullable();
$table->text('address')->nullable();
$table->date('registration_date');

// Status & Billing Fields
$table->string('status'); // e.g., 'Active', 'Suspended', 'Expired'
$table->timestamp('expiration')->nullable();
$table->timestamp('last_recharge_time')->nullable();
$table->decimal('special_price', 8, 2)->nullable();

// Other
$table->ipAddress('ip_address')->nullable();
$table->macAddress('mac_address')->nullable();
$table->foreignId('parent_id')->nullable(); // For linked accounts

$table->timestamps();

});
Customer Bill Schema (customer_bills table)
This table stores the individual invoices generated for each customer, typically on a monthly basis for PPPoE + Monthly Billing customers.

The MasterGroupAdminImportCommand.php script shows that each bill is tied to a customer, an operator, and the specific package at the time of billing.

php
Show full code block
// Inferred from /home/lupaels/IspBills/app/Console/Commands/MasterGroupAdminImportCommand.php

Schema::create('customer_bills', function (Blueprint $table) {
$table->id();
$table->decimal('amount', 8, 2);
$table->date('bill_date');
$table->date('due_date');
$table->string('status'); // e.g., 'Paid', 'Unpaid'
$table->text('validity_period'); // e.g., "2023-01-01 to 2023-01-31"

// Foreign Keys & Relationships
$table->foreignId('mgid');          // Belongs to a Master Group (the main ISP Admin)
$table->foreignId('gid');           // Belongs to a Group (the direct reseller/operator)
$table->foreignId('operator_id');   // Belongs to an Operator
$table->foreignId('customer_id');   // Belongs to a Customer
$table->foreignId('package_id');    // The package this bill is for
$table->foreignId('customer_zone_id')->nullable();

$table->timestamps();

});
Customer Payment Schema (customer_payments table)
This table logs every payment made by a customer, whether it's cash, online, or via a recharge card. The import script reveals its structure and connections.

php
Show full code block
// Inferred from /home/lupaels/IspBills/app/Console/Commands/MasterGroupAdminImportCommand.php

Schema::create('customer_payments', function (Blueprint $table) {
$table->id();
$table->decimal('amount', 8, 2);
$table->string('payment_method'); // e.g., 'Cash', 'Online', 'Card'
$table->string('transaction_id')->nullable(); // For online gateways
$table->text('notes')->nullable();

// Foreign Keys & Relationships
$table->foreignId('mgid');              // Belongs to a Master Group (the main ISP Admin)
$table->foreignId('gid');               // Belongs to a Group (the direct reseller/operator)
$table->foreignId('operator_id');       // Belongs to an Operator
$table->foreignId('customer_id');       // Belongs to a Customer
$table->foreignId('package_id');        // The package the payment is for
$table->foreignId('cash_collector_id')->nullable(); // The staff/manager who collected cash

$table->timestamps(); // The 'created_at' timestamp serves as the payment date

});
Key Relationships Summary
A Customer belongs to an Operator (reseller), a Package, and a BillingProfile.
A Customer has many CustomerBills and many CustomerPayments.
A CustomerBill belongs to a Customer and an Operator.
A CustomerPayment belongs to a Customer and an Operator.
This structure creates a robust and auditable system for managing the entire customer lifecycle, from provisioning and authentication to billing and payment history.

How does the application handle the multi-level commission for resellers and sub-resellers?

Gemini
Thinking
Of course. As a world-class software engineering assistant, I can provide a detailed explanation of how the multi-level commission system for resellers and sub-resellers works in the "IspBills" application, based on the provided documentation.

The application is built with a sophisticated, automated accounting system designed to handle complex, hierarchical sales structures. This allows an ISP (the "Admin") to sell services through multiple tiers of partners ("Resellers" and "Sub-Resellers").

Hierarchical Structure and Commission Flow
The core of the model is the business hierarchy, which the application defines as: Admin (ISP) -> Reseller (POP) -> Sub-Reseller (Sub-POP) -> Customer

When a customer at the bottom of this chain makes a payment, the commission is automatically calculated and distributed up the chain.

Configuration: The Admin configures the commission share for each Reseller. This is described in the documentation with a clear example: if a package is sold for 100TK and the reseller's share is 60%, the reseller earns 60TK and the Admin (ISP) earns 40TK. This same principle extends to sub-resellers, where a sub-reseller's commission is a portion of their direct parent reseller's share.

Automated Transaction Recording: The Feature.md file explicitly states that the system performs "Multi-level commission tracking" and "Commission distribution automation". When a customer payment is recorded (either automatically via an online gateway or manually for a cash payment), the system triggers a series of financial transactions.

Double-Entry Bookkeeping: The FINANCIAL_REPORTS_README.md file reveals that the application uses a robust double-entry accounting system. This system is built on two primary database tables: chart_of_accounts and financial_transactions.

The chart_of_accounts defines all financial accounts, including Revenue, Expense, Asset (like Cash), and Liability (like Accounts Payable). The example seeder shows specific accounts for 'Sales Revenue' and 'Sales Commission', which are crucial for this process.
The financial_transactions table records every debit and credit, ensuring the books are always balanced.
How a Payment is Distributed
When a customer payment is processed, the system automatically creates a set of balanced transactions to distribute the funds. Here’s a likely flow for a 100TK payment from a sub-reseller's customer:

Assumptions:

Reseller's share is 60% of the payment.
Sub-reseller's share is 50% of the Reseller's share.
Transaction Flow:

Customer Payment Received: The system records the full 100TK payment.
Debit Cash or Accounts Receivable for 100TK.
Sub-Reseller Commission: The sub-reseller earns 50% of the reseller's 60TK share, which is 30TK.
Credit the Sub-Reseller's Accounts Payable (money owed to them) for 30TK.
Reseller Commission: The reseller earns their 60% (60TK) minus the sub-reseller's portion (30TK), for a net earning of 30TK.
Credit the Reseller's Accounts Payable for 30TK.
Admin (ISP) Revenue: The Admin earns the remaining portion of the payment.
Credit Sales Revenue for 40TK.
This entire process is automated, as confirmed by the "Automatic Recording" feature, which handles the "Distribution of payments between ISP, reseller, sub-reseller".

User Roles and Visibility
The application's authentication system, defined in config/auth.php, establishes distinct user roles and "guards" for operators (which includes Admins, Resellers, and Sub-Resellers) and all_customers. This ensures that each user type has a panel with appropriate permissions and visibility.

Admin Panel: Has a complete overview of all revenue and commissions paid out.
Reseller Panel: Can track their total commission earned and the commission they owe to their sub-resellers.
Sub-Reseller Panel: Can track the commission they have earned from their own customer sales.
This multi-level commission system is a core part of the application's business logic, enabling ISPs to scale their operations through partnerships while maintaining accurate, automated, and transparent financial records for all parties involved.

Generated by Gemini 2.5 Pro

Lupael Vi Leader
How does the application use the MikroTik API for router management?

Gemini
Thinking
Of course. Based on the provided files, I can give you a detailed explanation of how the "IspBills" application leverages the MikroTik API for comprehensive router management, along with some code quality insights.

The primary file demonstrating this interaction is /home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php. This controller is responsible for a "one-click" automated configuration process that sets up a MikroTik router to work seamlessly with the IspBills RADIUS and billing system.

How the MikroTik API is Used
The application uses a third-party library, RouterOS\Sohag\RouterosAPI, to establish a connection and send commands to the MikroTik router. The process can be broken down into several key steps within the store method of the RouterConfigurationController.

  1. Connection and Authentication
    First, the application establishes a connection to the router using the API credentials (host, user, password, port) stored in the nas (Network Access Server) model.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php
//API
$config = [
'host' => $router->nasname,
'user' => $router->api_username,
'pass' => $router->api_password,
'port' => $router->api_port,
'attempts' => 1
];
$api = new RouterosAPI($config);
if (!$api->connect($config['host'], $config['user'], $config['pass'])) {
return redirect()->route('routers.index')->with('error', 'Could not connect to the router!');
}
Use code with care. Learn more
Before proceeding, it performs a crucial security check to ensure the provided API user has the necessary full or write permissions.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php
// check user group
$system_users = $api->getMktRows('user', ['name' => $config['user']]);
$api_user = array_shift($system_users);
$api_user_permission = $api_user['group'];
$required_permissions = ['full', 'write'];
if (in_array($api_user_permission, $required_permissions) == false) {
return redirect()->route('routers.index')->with('error', 'Not enough permission to setup your router. The API user requires full/write permission.');
}
Use code with care. Learn more
2. RADIUS Server Configuration
This is the most critical step. The application configures the router to use its own RADIUS server for handling authentication, authorization, and accounting for both ppp and hotspot services. It dynamically inserts the RADIUS server's IP address and the router's shared secret.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php
//Add radius information #hotspot,ppp
$menu = 'radius';
$rows = [
[
'accounting-port' => 3613,
'address' => $radius_server,
'authentication-port' => 3612,
'secret' => $router['secret'],
'service' => 'hotspot,ppp',
'timeout' => '3s',
'require-message-auth' => 'no',
]
];
$router_rows = $api->getMktRows($menu);
$api->removeMktRows($menu, $router_rows);
$api->addMktRows($menu, $rows);
Use code with care. Learn more
3. Hotspot Service Configuration
The API is used to configure every aspect of the Hotspot service for self-registration and automated billing:

System Identity: Sets the router's identity, which is used to map a hotspot user to a specific reseller.
Walled Garden: Adds the central application server's IP to the walled-garden ip list. This allows unauthenticated users to access the billing portal to register and pay.
Hotspot Profiles: It modifies all existing hotspot profiles to enable RADIUS authentication (use-radius = yes), MAC-based login (mac-auth-mode = mac-as-username-and-password), and sets various timeouts.
User Profiles: It configures on-login and on-logout scripts. These scripts are powerful automation tools; for example, the on-logout script ensures stale entries are removed from the hotspot host table.
4. PPPoE Service Configuration
Similarly, the API automates the setup for PPPoE customers:

Server Settings: It ensures all PPPoE servers use chap or pap authentication and allow only one session per user (one-session-per-host = yes).
RADIUS Integration: It enables RADIUS for AAA functions in the /ppp aaa menu.
Duplicate Session Handling: It adds an on-up script to all PPP profiles. This script checks for and disconnects duplicate sessions for the same user, which is a common operational issue.
IP Pools: It creates a dedicated IP pool on the router for suspended users.
5. Firewall and Network Rule Management
The application uses the API to programmatically add firewall rules to the router. This is used to enforce the billing policy at the network level. For example, it adds rules to drop all traffic from the IP pool assigned to suspended users, effectively blocking their internet access.

php
Show full code block
// /home/lupaels/IspBills/app/Http/Controllers/RouterConfigurationController.php
//Drop Suspended pool
$drop_rules = [
[
'chain' => 'input',
'src-address' => '100.65.96.0/20',
'action' => 'drop',
'comment' => 'drop suspended pool',
],
];
$api->addMktRows('ip_firewall_filter', $drop_rules);
Use code with care. Learn more
Code Quality and Suggestions
The RouterConfigurationController.php is a great example of infrastructure automation, but it could be improved for better maintainability and robustness.

Refactor into Smaller Services: The store method is very long and handles the configuration for multiple services (RADIUS, Hotspot, PPPoE, Firewall). This logic could be extracted into dedicated Action or Service classes, such as ConfigureHotspotAction.php or PppoeConfigurationService.php. This would make the code more readable, testable, and reusable.

Centralize Configuration Values: The script contains hardcoded values like the suspended user IP range (100.65.96.0/20) and various timeouts. These should be moved into dedicated configuration files (e.g., config/mikrotik.php). This is especially important for the suspended pool IP, which is hardcoded in the firewall rule but dynamically fetched from another controller (SuspendedUsersPoolController) when creating the pool. A mismatch here would break the suspension feature.

I would suggest creating a new configuration file:

New file: mikrotik.php
+14
Show full code block

[ 'name' => 'suspended_users_pool', 'range' => env('MIKROTIK_SUSPENDED_POOL_RANGE', '100.65.96.0/20'), ], 'radius' => [ 'accounting_port' => 3613, 'authentication_port' => 3612, 'timeout' => '3s', ], // ... other settings ]; Use code with care. Learn more And then reference these values in the controller, for instance: config('mikrotik.suspended_pool.range'). Improve Error Handling: The initial connection check is good, but the permission check could fail with an error if the API user belongs to a group that doesn't exist. Adding a check for the existence of $api_user before accessing its group key would make it more resilient. RouterConfigurationController.php return redirect()->route('routers.index')->with('error', 'Could not connect to the router!'); } Use code with care. Learn more plaintext // check user exists Use code with care. Learn more plaintext if (empty($api->getMktRows('user', ['name' => $config['user']]))) { Use code with care. Learn more plaintext return redirect()->route('routers.index')->with('error', 'The API user does not exist on the router.'); Use code with care. Learn more plaintext } Use code with care. Learn more plaintext // check user group $system_users = $api->getMktRows('user', ['name' => $config['user']]); $api_user = array_shift($system_users); Use code with care. Learn more plaintext Use code with care. Learn more In summary, the application uses the MikroTik API as a powerful Infrastructure as Code tool, automating what would otherwise be a complex and error-prone manual setup. It directly translates the application's business logic (billing, user status) into concrete network configurations (firewall rules, user profiles).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions