ISP Orbit — Expired Customer Popup Portal Setup Guide

১. Feature-এর কাজ

Popup Enabled হলে

Bill/expiry + grace শেষ হলে PPPoE Secret enabled থাকবে।

Customer-এর original package profile মনে রাখা হবে।

MikroTik profile EXPIRED হবে।

সাধারণ internet বন্ধ থাকবে, কিন্তু Billing Portal খুলবে।

Payment হলে original profile ফিরে full internet চালু হবে।

Popup Disabled হলে

আগের নিয়মে PPPoE Secret সম্পূর্ণ disabled হবে।

Payment হলে Secret আবার enabled হবে।

২. নতুন ISP client-এর সিদ্ধান্ত

Client-কে জিজ্ঞেস করবেন:

Bill শেষ হলে customer-এর line পুরো বন্ধ করবেন, নাকি restricted রেখে payment popup দেখাবেন?

Client Popup না চাইলে

Company Expiry Popup Portal = Disabled
Router Popup Portal Status = Disabled

এক্ষেত্রে Router-এ EXPIRED profile বা captive portal setup দরকার নেই।

Client Popup চাইলে

Company Expiry Popup Portal = Enabled

প্রতিটি MikroTik Router-এ:

Popup Portal Status = Enabled
Restricted PPP Profile = EXPIRED

প্রতিটি Router-এ নিচের MikroTik setup আলাদাভাবে করতে হবে।

৩. Software Portal প্রস্তুতি

Public URL:

https://CLIENT-DOMAIN.com/expired

Required Laravel files:

app/Http/Controllers/ExpiryPortalController.php
resources/views/public/expiry-portal.blade.php
routes/web.php

Live check:

php -l app/Http/Controllers/ExpiryPortalController.php
php -l routes/web.php
php artisan optimize:clear
php artisan route:list --name=expiry-portal

Expected:

GET|HEAD  expired
POST      expired/lookup

Browser-এ /expired খুললে Admin login নয়, public portal আসতে হবে।

৪. Scheduler/Cron যাচাই

Server cron-এ Laravel scheduler প্রতি মিনিটে চলতে হবে:

* * * * * /usr/local/bin/ea-php82 /FULL-PROJECT-PATH/artisan schedule:run >> /dev/null 2>&1

Application schedule:

billing:run                       প্রতিদিন 00:10
mikrotik:process-pending-actions  প্রতি 5 মিনিট

Check:

php artisan schedule:list

Pending retry:

php artisan mikrotik:process-pending-actions

৫. Router Backup ও Safe Mode

/system backup save name=before-isp-orbit-popup
/export file=before-isp-orbit-popup

Safe Mode:

Keyboard থেকে Ctrl + X

Prompt-এর শেষে <SAFE> দেখলে Safe Mode চালু। কাজ ঠিক হলে আবার keyboard থেকে Ctrl + X চাপলে commit হবে।

৬. Router Variables

Portal Domain: CLIENT-DOMAIN.com
Portal URL: CLIENT-DOMAIN.com/expired
Profile: EXPIRED
Restricted Network: 10.10.10.0/24
Router IP: 10.10.10.1
Pool: 10.10.10.2-10.10.10.254
Proxy Port: 8182

Portal IP resolve:

:put ("PORTAL-IP=" . [:resolve "CLIENT-DOMAIN.com"])

DNS/IP পরিবর্তন হলে IP আবার যাচাই করবেন।

৭. Restricted Pool

Check:

/ip pool print detail where name="captive-portal-pool"

না থাকলে:

/ip pool add name=captive-portal-pool ranges=10.10.10.2-10.10.10.254

অন্য network-এর সঙ্গে subnet conflict আছে কি না আগে দেখবেন।

৮. EXPIRED PPP Profile

Check:

/ppp profile print detail without-paging where name="EXPIRED"

না থাকলে:

/ppp profile add name=EXPIRED local-address=10.10.10.1 remote-address=captive-portal-pool rate-limit=256k/256k address-list=captive-portal-users dns-server=10.10.10.1 only-one=yes

Final profile:

name=EXPIRED
local-address=10.10.10.1
remote-address=captive-portal-pool
rate-limit=256k/256k
address-list=captive-portal-users
dns-server=10.10.10.1
on-up=""
on-down=""

অতিরিক্ত static address-list script রাখবেন না:

/ppp profile set [find where name="EXPIRED"] on-up="" on-down=""

৯. DNS ও Web Proxy

/ip dns set allow-remote-requests=yes

Proxy:

/ip proxy set enabled=yes port=8182 cache-on-disk=no max-cache-size=none

Check:

/ip proxy print

Expected:

enabled=yes
port=8182
cache-on-disk=no

১০. Portal IP Allow-list

PORTAL-IP-এর জায়গায় resolved IP দিন:

/ip firewall address-list add list=captive-portal-allow address=PORTAL-IP comment="isp-orbit-popup-portal"

Verify:

/ip firewall address-list print detail without-paging where comment="isp-orbit-popup-portal"

Entry disabled (X) থাকা যাবে না।

১১. NAT Rules

Required logical order:

1. Portal Server Allow
2. HTTP Redirect → 8182
3. Portal Server Masquerade
4. DNS TCP Redirect
5. DNS UDP Redirect

/ip firewall nat add chain=dstnat action=accept src-address-list=captive-portal-users dst-address-list=captive-portal-allow comment="captive-portal-allow-server-nat"
/ip firewall nat add chain=dstnat action=redirect to-ports=8182 protocol=tcp src-address-list=captive-portal-users dst-port=80 comment="captive-portal-redirect"
/ip firewall nat add chain=srcnat action=masquerade src-address-list=captive-portal-users dst-address-list=captive-portal-allow comment="captive-portal-allow-server-srcnat"
/ip firewall nat add chain=dstnat action=redirect protocol=tcp src-address-list=captive-portal-users dst-port=53 comment="captive-portal-dns-tcp"
/ip firewall nat add chain=dstnat action=redirect protocol=udp src-address-list=captive-portal-users dst-port=53 comment="captive-portal-dns-udp"

Order:

/ip firewall nat move [find where comment="captive-portal-allow-server-nat"] 0
/ip firewall nat move [find where comment="captive-portal-redirect"] 1

Verify:

/ip firewall nat print detail without-paging where comment~"captive-portal"

Duplicate rule রাখা যাবে না।

১২. Firewall Filter Rules

Required forward order:

1. Portal Server Allow
2. Other HTTPS Reject
3. Remaining Internet Block

Input:

4. Router DNS UDP Allow
5. Router DNS + Proxy TCP Allow

/ip firewall filter add chain=forward action=accept src-address-list=captive-portal-users dst-address-list=captive-portal-allow comment="captive-portal-allow-server"
/ip firewall filter add chain=forward action=reject reject-with=tcp-reset protocol=tcp src-address-list=captive-portal-users dst-port=443 comment="isp-orbit-popup-drop-https"
/ip firewall filter add chain=forward action=reject reject-with=icmp-network-unreachable src-address-list=captive-portal-users comment="isp-orbit-popup-block-all"
/ip firewall filter add chain=input action=accept protocol=udp src-address-list=captive-portal-users dst-port=53 comment="captive-portal-allow-router"
/ip firewall filter add chain=input action=accept protocol=tcp src-address-list=captive-portal-users dst-port=53,8182 comment="captive-portal-allow-router"

Order:

/ip firewall filter move [find where comment="captive-portal-allow-server"] 0
/ip firewall filter move [find where comment="isp-orbit-popup-drop-https"] 1
/ip firewall filter move [find where comment="isp-orbit-popup-block-all"] 2

Verify:

/ip firewall filter print detail without-paging where src-address-list="captive-portal-users"

১৩. Web Proxy Access Rules

Final দুইটি rule:

/ip proxy access add src-address=10.10.10.0/24 dst-host=CLIENT-DOMAIN.com action=allow comment="isp-orbit-popup-allow-host"
/ip proxy access add src-address=10.10.10.0/24 action=deny redirect-to="CLIENT-DOMAIN.com/expired" comment="isp-orbit-popup-redirect"

Order:

/ip proxy access move [find where comment="isp-orbit-popup-allow-host"] 0
/ip proxy access move [find where comment="isp-orbit-popup-redirect"] 1

Verify:

/ip proxy access print detail without-paging where comment~"isp-orbit-popup"
:put ("FINAL-PROXY=" . [:len [/ip proxy access find where comment~"isp-orbit-popup"]])

Expected:

FINAL-PROXY=2

পুরোনো domain-এর duplicate proxy rules রাখবেন না।

১৪. Software Final Settings

Company

General Settings
→ Enable Expiry Popup Portal
→ Enabled
→ Save

Router

MikroTik Router Edit
→ Popup Portal Status = Enabled
→ Restricted PPP Profile = EXPIRED
→ Update Router

Decision:

Company Popup

Router Popup

Result

Disabled

যেকোনো

Full Secret Disable

Enabled

Disabled

Full Secret Disable

Enabled

Enabled + EXPIRED

Restricted Popup

Enabled

Config/Profile missing

Safe Disable/Fallback

১৫. Dummy Customer Test

Real customer নয়, dedicated test customer ব্যবহার করুন:

Customer: Popup Portal Test
PPPoE: popup-test-01
Router: Test Router
Package: Valid package
Billing Type: Prepaid
Expiry Date: আগের দিন
Grace Days: 0
Service Status: Active
Auto Billing: Enabled

Secret create/sync করে নিশ্চিত করুন:

Secret Matched
Original Profile assigned
Disabled = No

Service ID:

SELECT id, service_code, pppoe_username, expiry_date, billing_blocked, billing_block_source, internet_access_mode
FROM customer_services
WHERE pppoe_username = 'popup-test-01';

Dry run:

php artisan billing:run --date=YYYY-MM-DD --service=SERVICE_ID --dry-run

Actual:

php artisan billing:run --date=YYYY-MM-DD --service=SERVICE_ID

১৬. Restricted Result Check

SELECT id, service_code, pppoe_username, billing_blocked, billing_block_source,
       internet_access_mode, internet_access_changed_at, restricted_from_profile,
       pending_mikrotik_action, pending_mikrotik_source, pending_mikrotik_error
FROM customer_services
WHERE id = SERVICE_ID;

Expected:

billing_blocked = 1
billing_block_source = prepaid_expiry / postpaid_due
internet_access_mode = restricted
restricted_from_profile = Original Package Profile
pending_mikrotik_action = NULL
pending_mikrotik_error = NULL

MikroTik sync:

SELECT pppoe_username, profile, disabled, is_present, synced_at
FROM mikrotik_pppoe_secrets
WHERE pppoe_username = 'popup-test-01';

Expected:

profile = EXPIRED
disabled = 0
is_present = 1

Router:

/ppp secret print detail where name="popup-test-01"

১৭. Browser Redirect Test

Spare Router/ONU-তে dummy PPPoE দিন।

/ppp active print detail where name="popup-test-01"

Expected IP:

10.10.10.x

Browser:

http://neverssl.com

Expected redirect:

https://CLIENT-DOMAIN.com/expired

Hits:

/ip proxy access print detail without-paging where comment~"isp-orbit-popup"

১৮. Payment Restore Test

Full payment-এর পরে expected:

billing_blocked = 0
billing_block_source = NULL
internet_access_mode = normal
restricted_from_profile = NULL
pending_mikrotik_action = NULL

MikroTik:

profile = Original Package Profile
disabled = 0

১৯. Existing Blocked Customer Check

SELECT billing_block_source, internet_access_mode, COUNT(*) AS total
FROM customer_services
WHERE billing_blocked = 1
GROUP BY billing_block_source, internet_access_mode;

Popup eligible:

prepaid_expiry
postpaid_due

Popup-এ নেওয়া যাবে না:

manual
reseller_wallet

আগে থেকেই disabled eligible customerকে plain SQL দিয়ে restricted করবেন না। Central application service বা dedicated bulk command ব্যবহার করবেন।

২০. কোন Customer Popup দেখবে

Required condition:

billing_blocked = 1
billing_block_source = prepaid_expiry অথবা postpaid_due
internet_access_mode = restricted
MikroTik Secret disabled = no
MikroTik Profile = EXPIRED

Popup দেখবে না:

Valid customer
Free customer
Manual block
Reseller wallet block
Inactive/Left customer
Secret সম্পূর্ণ disabled customer

২১. Troubleshooting

Portal না খুললে

Company Popup Enabled?
Router Popup Enabled?
Profile exact EXPIRED?
Secret disabled=no?
Secret profile=EXPIRED?
PPP active IP=10.10.10.x?
IP captive-portal-users list-এ আছে?
Portal IP allow-list-এ আছে?
Proxy port 8182 enabled?
NAT packets বাড়ছে?
Proxy redirect hits বাড়ছে?

Commands:

/ppp active print detail where name="USERNAME"
/ip firewall address-list print detail without-paging where list="captive-portal-users"
/ip firewall nat print stats detail without-paging where comment~"captive-portal"
/ip proxy access print detail without-paging where comment~"isp-orbit-popup"

Portal খুলে কিন্তু account না পেলে

সম্ভাব্য কারণ:

manual block
reseller_wallet block
billing_blocked = 0
service active নয়
connection type pppoe নয়
Customer Code/Mobile ভুল

Payment হয়েছে কিন্তু restore হয়নি

SELECT id, service_code, pending_mikrotik_action, pending_mikrotik_source, pending_mikrotik_error
FROM customer_services
WHERE id = SERVICE_ID;

Retry:

php artisan mikrotik:process-pending-actions

২২. Rollback

প্রথমে:

Company Expiry Popup Portal = Disabled

তারপর:

Router Popup Portal Status = Disabled

Future expiry customer আগের full-disable logic ব্যবহার করবে।

২৩. Final Backup

/system backup save name=isp-orbit-popup-final
/export file=isp-orbit-popup-final

Server files ও database backup-ও রাখবেন।

২৪. Final Delivery Checklist

[ ] Client Popup চায় কি না নিশ্চিত
[ ] /expired portal live
[ ] Laravel files deployed
[ ] Scheduler/Cron active
[ ] Router API connected
[ ] Router backup নেওয়া
[ ] Restricted pool configured
[ ] EXPIRED profile configured
[ ] DNS enabled
[ ] Web Proxy 8182 enabled
[ ] Portal IP allow-listed
[ ] NAT order correct
[ ] Filter order correct
[ ] Final Proxy rules = 2
[ ] Company Popup Enabled
[ ] Router Popup Enabled
[ ] Dummy expiry test passed
[ ] Browser redirect test passed
[ ] Payment restore test passed
[ ] Pending retry test passed
[ ] Temporary test rules removed
[ ] Final backup/export নেওয়া

২৫. Client-কে বলার জন্য Ready Message

আপনার software-এ Expiry Popup Portal চালু করা হয়েছে। Customer-এর bill ও grace period শেষ হলে PPPoE Secret বন্ধ হবে না; customer restricted profile-এ গিয়ে billing portal দেখতে পারবে। Payment সম্পন্ন হলে software automatic original package profile ফিরিয়ে full internet চালু করবে। Valid, Free এবং manually blocked customer এই automation-এ প্রভাবিত হবে না।











-----------------------------------
-----------------------------------
-----------------------------------
-----------------------------------
-----------------------------------
-----------------------------------
-----------------------------------