DEV Community

Cover image for What I Learned Building a Real-Time Pulsa & Top-Up Backend with Node.js
Hery
Hery

Posted on

What I Learned Building a Real-Time Pulsa & Top-Up Backend with Node.js

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"
} 
Enter fullscreen mode Exit fullscreen mode

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)