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
And, of course, we fixed some infrastructure issues along the way.
- 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.
- 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}}'
- 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.
- 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.
- 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
Meanwhile, the Security Bot runs hourly scans, generating reports and sending alerts if vulnerabilities are found.
- 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
-
Links & Resources
GitHub Repository: DanielIoni-creator/MyZubsterGateway
Live Demo: https://myzubster.com
My Dev.to Profile: @danielioni
My GitHub: DanielIoni-creator
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)