💳 Building a Monero Payment Gateway with Node.js: MyZubster + Cardputer
Node.js · Express · Monero · Cardputer · IoT · Open Source
What happens when you combine a small IoT device with a privacy-focused cryptocurrency?
For the MyZubster ecosystem, I wanted to experiment with exactly that question.
The result is a modular Monero payment gateway designed to connect devices such as the Cardputer with a backend capable of creating payment requests, generating Monero payment URIs, storing payment records, and exposing an API for payment workflows.
This article explains how the prototype works and what needs to be added to turn it into a production-grade payment system.
🚀 The Idea
The basic workflow is simple:
Cardputer
↓
Payment Request
↓
MyZubster Gateway
↓
Monero Payment Request
↓
QR Code
↓
User's Monero Wallet
↓
XMR Transaction
↓
Payment Verification
The Cardputer doesn't need to understand the entire payment infrastructure.
It only needs to communicate with the Gateway.
This separation makes the architecture easier to extend to robots, vending machines, kiosks, IoT devices, and other autonomous services.
🧱 Architecture
The prototype is built around four main components:
1. Cardputer
The physical interface.
It can identify a tag or trigger a payment request and communicate with the application layer.
2. Android or Client Application
The client communicates with the Cardputer and calls the Gateway API.
3. MyZubster Gateway
The backend manages:
- payment requests;
- payment IDs;
- amounts;
- destination information;
- payment status;
- persistence;
- API communication.
4. Monero Infrastructure
The final transaction is made using a Monero wallet.
The important distinction is that creating a payment record is not the same as verifying an on-chain Monero transaction.
The current prototype focuses on the gateway workflow; automatic blockchain verification is a next development step.
⚙️ Node.js Gateway
The backend uses Node.js and Express.
A minimal server starts like this:
const express = require("express");
const fs = require("fs");
const path = require("path");
const cors = require("cors");
const app = express();
const port = 3000;
app.use(cors());
app.use(express.json());
const DATA_FILE = path.join(__dirname, "payments.json");
The API can then expose payment endpoints to other parts of the ecosystem.
💳 Creating a Payment
The first endpoint creates a payment request.
app.post("/api/cardputer/payment/create", (req, res) => {
const { tag_id, amount } = req.body;
const payment_id =
"pay_" +
Date.now() +
Math.random().toString(36).substring(2, 7);
const newPayment = {
id: payment_id,
tag_id,
amount: parseFloat(amount),
status: "pending",
created_at: new Date().toISOString()
};
payments.push(newPayment);
savePayments(payments);
res.json({
success: true,
payment_id,
amount: parseFloat(amount),
tag: tag_id
});
});
The important concept here is the payment ID.
Every request gets its own identifier so that the system can track the payment independently.
🔄 Payment Status
The Gateway also exposes an endpoint for retrieving payment status.
app.get("/api/cardputer/payment/status/:payment_id", (req, res) => {
const payment = payments.find(
p => p.id === req.params.payment_id
);
if (!payment) {
return res.status(404).json({
success: false,
error: "Payment not found"
});
}
res.json({
success: true,
payment
});
});
A device can therefore ask:
Has payment X been completed?
and receive the current state from the Gateway.
📡 Cardputer Integration
The Cardputer becomes an interface between the physical world and the payment backend.
A simplified workflow looks like this:
User
↓
Cardputer
↓
Tag / Device ID
↓
Android Application
↓
MyZubster Gateway
↓
Payment Request
↓
Monero QR
This is particularly interesting for autonomous devices.
Imagine a robot that provides a service.
Instead of integrating a complete payment system directly into the robot, the robot can communicate with the Gateway.
🤖 From Payments to Robots
This architecture can eventually support workflows such as:
User requests service
↓
Robot creates payment request
↓
Gateway generates payment
↓
User pays XMR
↓
Gateway verifies transaction
↓
Robot receives authorization
↓
Service begins
This is where the payment gateway becomes more than a cryptocurrency API.
It becomes part of an autonomous service infrastructure.
💾 Persistence
For the prototype, payment records can be stored in a JSON file.
Example:
[
{
"id": "pay_example",
"tag_id": "CARDPUTER-001",
"amount": 0.01,
"status": "pending",
"created_at": "2026-08-11T08:39:35.413Z"
}
]
The advantage is simplicity.
The disadvantage is that JSON files are not the right choice for a high-volume production payment system.
A future version could use PostgreSQL or another transactional database.
🔐 Security
Payment infrastructure requires a different level of care than a normal prototype.
The following information should never be committed to Git:
Private keys
Seed phrases
Wallet credentials
API secrets
.env files
For example:
.env
wallet-credentials.json
*.key
The Gateway should also eventually include:
- authentication;
- authorization;
- request validation;
- rate limiting;
- HTTPS;
- structured logging;
- database transactions;
- secret management;
- audit trails.
Most importantly, the backend should never expose private wallet credentials to clients or IoT devices.
💰 Monero Payment Verification
There is an important distinction between:
Payment status in the application
and
Payment confirmed on the Monero network.
A production implementation should not simply trust:
{
"status": "paid"
}
because a client could potentially manipulate such a value.
Instead, the Gateway should independently verify the transaction through Monero infrastructure.
The intended architecture is:
Payment Request
↓
Monero Address / Payment Identifier
↓
Blockchain Monitoring
↓
Transaction Detection
↓
Confirmation Check
↓
Gateway Status = PAID
Only after the required confirmation policy is satisfied should an autonomous service be authorized to continue.
⚡ Running with PM2
For development and deployment, PM2 can keep the Node.js process running.
pm2 start server.js --name myzubster-gateway
pm2 save
pm2 startup
This gives the service automatic restart capabilities.
For a real production deployment, I would also add monitoring, logs, backups, HTTPS, and proper infrastructure isolation.
🧪 Testing the API
Create a payment:
curl -X POST http://localhost:3000/api/cardputer/payment/create \
-H "Content-Type: application/json" \
-d '{"tag_id":"CARDPUTER-TEST-001","amount":0.01}'
Then retrieve its status:
curl \
http://localhost:3000/api/cardputer/payment/status/PAYMENT_ID
This makes it possible to test the backend independently of the physical hardware.
That is important when developing IoT systems.
🌍 Why This Matters for MyZubster
The interesting part isn't simply accepting XMR.
The bigger idea is connecting digital payments with physical systems.
The same Gateway architecture could eventually serve:
💳 Cardputer
↓
🤖 Robot
↓
🌱 Smart Garden
↓
🏪 Vending Machine
↓
🛸 Space Simulation
↓
🧠 AI Agent
Each system can communicate with the same payment infrastructure without implementing the entire payment stack independently.
🔮 What's Next?
The next stages of development are focused on moving from prototype to stronger infrastructure.
Planned improvements
- 🔗 Automatic Monero transaction monitoring
- ✅ Confirmation verification
- 🔔 Payment webhooks
- 📊 Gateway dashboard
- 🗄️ Database persistence
- 🔐 Stronger authentication
- 📱 Improved Cardputer integration
- 🤖 Robot payment workflows
- 🌐 Multi-device support
The long-term goal is to make the Gateway a reusable component of the MyZubster ecosystem.
🌱 From a Payment Gateway to an Autonomous Economy
This project started with a simple question:
Can a small physical device trigger a private digital payment workflow?
The answer is yes, at prototype level.
But the more interesting question is what happens next.
If a Cardputer can request a payment, a robot can request a payment.
If a robot can request a payment, an autonomous service can request a payment.
And if autonomous services can verify payments and execute tasks, we can start experimenting with a much broader concept:
machines participating in digital economic workflows.
That's the direction I'm exploring with MyZubster.
Not just cryptocurrency payments.
Not just robots.
Not just IoT.
But the infrastructure connecting them.
🔗 Source Code
The project is being developed openly:
GitHub:
https://github.com/DanielIoni-creator/I-ECO-01
Final Thoughts
The current Gateway is still an evolving project.
The prototype demonstrates the basic architecture:
Device
↓
API
↓
Payment Request
↓
Monero
↓
Verification
↓
Service
The next challenge is making every part of that pipeline more secure, reliable, and autonomous.
One device at a time.
One payment at a time.
One open-source module at a time.
🚀 MyZubster is building the bridge between software, physical devices, and privacy-focused payments.
Top comments (0)