What I Learned Building a Real-Time Pulsa & Top-Up Backend with Node.js
This isn't a tutorial β just a story of how I ended up building a backend system to handle real-time prepaid top-ups (pulsa, internet data, utility tokens, etc.) using plain Node.js and WebSocket.
The system is live, used daily by users, and processes transactions through bank transfer detection + external API triggers. Here's how it evolved, and what I learned from the process.
π§Ή Context
In my region, prepaid services like mobile data, electricity tokens (PLN), and even BPJS (national health insurance) payments are still very much in demand β and mostly processed manually.
I wanted to build something that can:
- Accept top-up requests from users
- Detect payment via bank mutation (MSSQL-based)
- Send that payment to a remote gateway
- Do all this in real-time with feedback to the frontend
π» The Stack
Nothing fancy. I started with:
- Node.js β to handle backend logic
- WS (WebSocket) β for bi-directional real-time updates
- MSSQL β to query latest transfers/mutations
- Filesystem β queueing requests via JSON files
- Axios β to send top-up commands to the gateway
The queue system is very basic: JSON files are dropped into a req/
folder, then scanned every minute for matching payments.
π Real-Time Looping
Each file contains a request like this:
{
"type": "MAXsi.ID TOPUP",
"kode": "IND10",
"tujuan": "0812700313",
"harga": 10313,
"nama": "Rizky",
"bank": "BRI",
"deviceId": "client-xyz"
}
Once a match is found in the bank mutation table (e.g. amount + name in keterangan
), the system triggers a request to an external API (in my case, OtomaX or a similar system).
The client is updated in real-time through the WebSocket connection.
π§ Things That Surprised Me
- π§΅ WebSocket is underrated. For transactional systems, it's way better than polling.
- βοΈ Parsing human-entered notes is unreliable. You'd be surprised how many ways someone can type "Rizky".
- βΊ Retry logic matters. Sometimes network flukes cause a miss, and the system needs to be idempotent.
- π File-based queuing works, if you're disciplined. For low-traffic systems, it's dead simple and avoids DB overhead.
π§ͺ Bank Mutation Matching Logic
This is the trickiest part. I check:
amount >= harga
keterangan LIKE %nama%
- and
timestamp
is within Β±45 mins
Even with that, I added safeguards like βprocessed filesβ tracker to avoid duplicate transactions.
βοΈ Closing Thoughts
This system isn't perfect. But it's been running daily, reliably handling:
- Pulsa top-ups
- Token listrik (prepaid electricity)
- Bill payments like BPJS and PBB
I learned a lot from this β especially about simplifying automation. Sometimes, you don't need Kubernetes or Kafka. Just a folder, a WebSocket, and some console.log
.
If you're building anything in this space β fintech, automation, hybrid local-digital systems β I'd love to hear how you tackle these things.
Top comments (0)