Building an IDC Automation System from Scratch: Tech Stack Choices and Lessons Learned
Background and Motivation
I’ve used quite a few IDC (Internet Data Center) systems before, including WHMCS and Magic Cube Finance (魔方财务). WHMCS is made by foreigners, localization is incomplete, some logic doesn’t fit Chinese usage, it’s pricey, and frankly, bloated. Magic Cube Finance is pretty good for domestic use, but it’s just as bloated as WHMCS and just as expensive. The so-called “cracked versions” of these two are even worse — it’s not uncommon to hear stories online of backdoors letting customer data get totally stolen.
Right now, I need a lightweight management system for my soon-to-launch “free VPS” service, and the requirements aren’t complicated — just customer, product, order, and billing management. The problems with existing systems were already mentioned. So, I decided to just write my own.
Tech Stack and Architecture Choices
Call this an “anti-overengineering” approach: no mindless following of frameworks or microservices trends.
| Module | Choice | Reason |
|---|---|---|
| Backend | Pure PHP 7.4+ | Zero dependencies, zero build, deploy instantly |
| Database | MySQL/MariaDB | PDO direct connection, no ORM, simple & reliable |
| Frontend | TailwindCSS + VanillaJS | CDN import, no node_modules or webpack hassle |
| Module Sys. | Custom Hook Mechanism | Plugin-based, core decoupled from business logic |
| Payments | Yipay Aggregation | Integrates Alipay/WeChat/QQ Wallet in one go |
| Framework | None | Just plain PHP, direct output, no Laravel/ThinkPHP |
The architecture is two layers: admin dashboard + user frontend. Both share the same database and core library. No API layer, no message queues, no Redis—it’s not that I think they’re bad, just not needed for this use case. The core principle is subtraction—only add dependencies when they’re absolutely necessary.
Core Module Design and Implementation
Modular Architecture (Hook System): This is the most central part of the system. I drew inspiration from Fossbilling (peer system with similar problems; their mapping makes secondary development for projects like VPS8 pretty tough) for the hook idea, implementing addHook / triggerHook mechanisms. Want to integrate a new control panel or payment channel? Just write a module, drop it in the modules/ folder—no need to touch the core code at all. The list of enabled modules is configured in modules/.enabled, similar to Laravel service provider registration.
Yipay Integration: Payment callback handling was the trickiest part. When an asynchronous notification comes in, first verify the MD5 signature, then update the invoice status and insert a payment record transactionally, then trigger the after_invoice_paid hook for follow-up by other modules. Idempotence is ensured by checking invoice.status !== 'paid' to prevent the same callback from triggering double activation.
Product & Order System: Supports monthly, quarterly, semi-annual, and annual pricing cycles. Each product can be linked to a server module. After a user places an order, statuses transition as pending → active → suspended/cancelled/terminated. Right now, provisioning is handled synchronously; in the future, I’ll add cron jobs for automated suspension and destruction.
Lessons and Pitfalls
AI-Generated Code “Hallucinations”: Most of this system was built with substantial help from DeepSeek. The biggest trap was AI “confidently” making up functions that don’t exist. For example, when I asked it to write a PDO query wrapper, it just used $db->select(), a chainable method that doesn’t exist. Solution: manually review every line of AI-generated code, and handwrite critical business logic (payments, transactions).
Module Load Order & Hook Conflicts: Earlier versions loaded modules without sorting, so one module’s hook could override another’s of the same name. Later, I added a priority parameter and load order control: the order in .enabled determines the sequence they’re loaded.
Operations and Security
Still basic for now, but all the essentials for production are there:
- Passwords are stored with
password_hash()+bcrypt - Admin and user sessions are separated, each with independent logins
- Database connection info is in
config/database.php, web directory can’t be directly accessed - Simple permission distinction for the backend (superadmin/admin)
Planned features: automatic database backup, encrypted storage for API keys, audit logging.
Conclusion and Outlook
This system took about 6 hours of spare time to build, largely assisted by DeepSeek. The core value is extreme simplicity + modularity—no frameworks, no third-party libraries, just unzip and run. Want to add a feature? Just write a module.
All basic functions are working. Next steps:
- Write a PVE (Proxmox VE) integration module for automated provisioning
- Improve the payment module to support more gateways
- Add scheduled tasks for auto-suspension and deletion of expired orders
- Add backup and security auditing features
The project is now open source, with full development docs in docs.md, a module development example in modules/demo/, and the Yipay module at modules/yipay/.
My biggest insight: in the right scenarios, doing less (subtraction) is harder and more valuable than piling on more tech stacks. Feel free to reach out and discuss—I’m happy to share everything I know.
