DEV Community

Daniel Ioni
Daniel Ioni

Posted on

MyZubsterGateway: From Health Checks to Security Bots – A Development Log 🚀

 MyZubsterGateway: From Health Checks to Security Bots – A Development Log 🚀

Today was a productive session. Here's everything we built, fixed, and shipped.
The Context

MyZubster is an open-source, privacy-first ecosystem for peer-to-peer services, powered by Monero payments and Tor anonymity. At its heart lies the MyZubsterGateway – the engine that handles all Monero interactions: generating unique subaddresses, monitoring payments, and sending webhook notifications when transactions are confirmed.

Today, we took the gateway from a "working prototype" to a production-ready system by adding three critical components:

Health check endpoint – for monitoring

Webhook retry mechanism – for reliability

Security bot – for continuous vulnerability scanning
Enter fullscreen mode Exit fullscreen mode

And, of course, we fixed some infrastructure issues along the way.

  1. Health Check Endpoint

The first step was simple but essential: a health check endpoint to monitor the gateway's status.
javascript

// In server.js
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});

Why? In any production system, you need to know if the service is alive. This endpoint is the first line of defense in observability.

  1. Webhook Retry Mechanism with Exponential Backoff

The most important feature we built today: a reliable webhook delivery system.
The Problem

When a payment is confirmed, the gateway sends a webhook to the merchant's server. If that server is temporarily down – due to a restart, network issue, or maintenance – the webhook is lost, and the order never updates.
The Solution

We built a WebhookService that automatically retries failed webhook deliveries using exponential backoff:
javascript

// services/webhookService.js
class WebhookService {
constructor() {
this.retryDelays = [5, 30, 120, 600]; // 5s, 30s, 2m, 10m
this.maxRetries = this.retryDelays.length;
}

async sendWebhook(url, payload, retryCount = 0) {
// Attempt delivery with timeout and status code validation
// On failure, schedule next retry with backoff
}
}

Why exponential backoff? If a webhook fails due to a temporary issue, retrying immediately won't help. By waiting progressively longer, we give the downstream service time to recover without overwhelming it.
Integration with PaymentMonitor

The PaymentMonitor now uses the webhook service when a payment is confirmed:
javascript

if (result.status === 'confirmed') {
const webhookResult = await WebhookService.sendWebhookAsync(
tx.webhookUrl,
{
orderId: tx.orderId,
amount: tx.amount,
status: 'confirmed',
txHash: result.txHash
}
);
}

If the webhook fails permanently (after all retries), the order is marked as webhookFailed for manual review.
Test Endpoint

We added a test endpoint to validate the logic without waiting for a real payment:
bash

curl -X POST http://localhost:3002/api/test-webhook \
-H "Content-Type: application/json" \
-d '{"targetUrl":"https://your-webhook-endpoint","payload":{"test":true}}'

  1. Security Bot – Continuous Vulnerability Scanning

Security is not a one-time activity. We built a Python bot that runs hourly scans using industry-standard tools:
Tools Integrated
Tool Purpose
nmap Port scanning and service detection
nikto Web server vulnerability scanning
sqlmap SQL injection detection
gobuster Directory and file busting
DeepSeek Integration

All scan results are sent to DeepSeek R1:1.5B (running locally via Ollama) for automated analysis and recommendations:
python

def call_deepseek(prompt, context):
payload = {
"model": "deepseek-r1:1.5b",
"prompt": f"{prompt}\n\nCONTESTO:\n{context[:3000]}",
"stream": False
}
response = requests.post(DEEPSEEK_URL, json=payload)
return response.json().get('response')

Example Report
json

{
"timestamp": "2026-07-24T13:49:17.436Z",
"target": "https://myzubster.com",
"scans": {
"nmap": "...",
"nikto": "...",
"sqlmap": "...",
"gobuster": "..."
},
"deepseek_analysis": "Vulnerabilities found: ..."
}

Challenge: Gobuster and Catch-All 200

The biggest challenge was gobuster failing because myzubster.com returns status code 200 and length 468 for every URL (a catch-all configuration).

Fix:
bash

gobuster dir -u https://myzubster.com \
-w /usr/share/wordlists/dirb/common.txt \
-t 50 \
--no-error \
--status-codes-blacklist "" \
--status-codes 200,204,301,302,307,403 \
--exclude-length 468

The --exclude-length 468 tells gobuster to ignore responses with that length, effectively filtering out false positives.

  1. Infrastructure: Fixing MongoDB

During development, MongoDB wouldn't start. The logs showed:
text

Writing to log file failed, aborting application

The issue? File permissions. MongoDB couldn't write to /var/log/mongodb.

Fix:
bash

mkdir -p /var/log/mongodb /var/lib/mongodb
chown -R mongodb:mongodb /var/log/mongodb /var/lib/mongodb
chmod 755 /var/log/mongodb /var/lib/mongodb
systemctl restart mongod

Lesson learned: Always check file permissions. A small oversight can block the entire system.

  1. The Flow: End-to-End

Here's how everything works together:

User places an order → Gateway generates a unique Monero subaddress

User sends Monero to that subaddress

PaymentMonitor detects the transaction (every 30 seconds)

WebhookService attempts to deliver the confirmation

If it fails → retry with backoff (5s → 30s → 2m → 10m)

If all retries fail → order marked as webhookFailed for manual review
Enter fullscreen mode Exit fullscreen mode

Meanwhile, the Security Bot runs hourly scans, generating reports and sending alerts if vulnerabilities are found.

  1. What's Next?

This is just the beginning. The roadmap ahead:
Priority Task
🔴 High Mainnet Monero – configure for mainnet (currently testnet)
🔴 High Webhook testing – verify in production with a real endpoint
🟡 Medium NFC payments API – prepare for mobile app integration
🟡 Medium Admin dashboard – statistics and order management
🟢 Low Docker support – one-command deployment

  1. Links & Resources

    GitHub Repository: DanielIoni-creator/MyZubsterGateway

    Live Demo: https://myzubster.com

    My Dev.to Profile: @danielioni

    My GitHub: DanielIoni-creator

  2. Final Thoughts

Today's session was a perfect example of incremental improvement. We didn't build anything revolutionary – just solid, reliable features that make the system production-ready.

Every webhook matters. Every order counts. And now, MyZubsterGateway makes sure neither is lost.

Tags: #MyZubster #Monero #Webhooks #NodeJS #MongoDB #Security #DevOps #OpenSource #DeepSeek

Top comments (0)