Paycrypt is a multi-chain cryptocurrency payment system that enables users to purchase utility services (airtime, internet, electricity, TV) using stablecoins across three blockchain networks: Base, Lisk, and Celo.
Paycrypt Backend
βββ API Layer (Next.js Routes)
βββ Database (MongoDB)
βββ Blockchain Integration (Web3)
βββ Payment Processing (VTPass API)
βββ Sync Services (Cron Jobs)
| Network | Chain ID | Contract Address | Status |
|---|---|---|---|
| Base | 8453 | 0x0574A0941Ca659D01CF7370E37492bd2DF43128d | β Active |
| Lisk | 1135 | 0x7Ca0a469164655AF07d27cf4bdA5e77F36Ab820A | β Active |
| Celo | 42220 | 0x8CD2295407B9429286457e76848edeE6d1c257f2 | β Active |
- USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913)
- USDT (0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2)
- SEND (0xeab49138ba2ea6dd776220fe26b7b8e446638956)
- USDT (0x05D032ac25d322df992303dCa074EE7392C117b9)
- USDC (0xF242275d3a6527d877f2c927a82D9b057609cc71)
- cUSD (0x765DE816845861e75A25fCA122bb6898B8B1282a)
- CELO (0x471EcE3750Da237f93B8E339c536989b8978a438)
- USDT (0x617f3112bf5397D0467D315cC709EF968D9ba546)
- USDC (0xef4229c8c3250C675F21BCefa42f58EfbfF6002a)
1. User selects service (Airtime, Internet, Electricity, TV)
2. Chooses blockchain network (Base, Lisk, or Celo)
3. Selects stablecoin payment method
4. Approves token transfer on blockchain
5. System creates order in database
6. Payment is processed through VTPass API
7. Utility service is activated (airtime credited, etc.)
8. Transaction receipt is generated
API Request
β
Validate Request Data
β
Check/Store Order in MongoDB
β
Process Payment via VTPass
β
Update Order Status
β
Return Response to Frontend
Each transaction is recorded with:
{
requestId: String, // Unique request identifier
userAddress: String, // Customer wallet address
transactionHash: String, // Blockchain transaction ID
serviceType: String, // 'airtime' | 'internet' | 'electricity' | 'tv'
serviceID: String, // Provider service ID
variationCode: String, // Service variation (e.g., plan type)
customerIdentifier: String, // Phone number or meter number
amountNaira: Number, // Amount in Nigerian Naira
cryptoUsed: String, // Token used (e.g., USDC)
cryptoSymbol: String, // Token symbol
chainId: Number, // 8453 (Base), 1135 (Lisk), or 42220 (Celo)
chainName: String, // 'Base', 'Lisk', or 'Celo'
onChainStatus: String, // 'confirmed' | 'failed'
vtpassStatus: String, // 'pending' | 'successful' | 'failed'
createdAt: Date, // Order creation timestamp
updatedAt: Date // Last update timestamp
}POST /api/airtime
{
requestId, billersCode, serviceID, variation_code,
amount, phone, cryptoUsed, cryptoSymbol,
transactionHash, userAddress, chainId, chainName
}
POST /api/internet
{
requestId, billersCode, serviceID, variation_code,
amount, phone, cryptoUsed, cryptoSymbol,
transactionHash, userAddress, chainId, chainName
}
POST /api/electricity
{
requestId, meterNumber, serviceID, variation_code,
amount, phone, cryptoUsed, cryptoSymbol,
transactionHash, userAddress, chainId, chainName
}
Response includes: prepaidToken (meter reading details)
POST /api/tv
{
requestId, billersCode, serviceID, variation_code,
amount, phone, cryptoUsed, cryptoSymbol,
transactionHash, userAddress, chainId, chainName
}
GET /api/history?userAddress=0x...&chainId=8453
Returns: All transactions for a user, optionally filtered by chain
GET /api/health
Returns: API status and runs any pending data migrations
When the backend starts, it automatically:
- Checks Database Connection - Ensures MongoDB is accessible
- Runs Migration - Updates old orders without chain information
- Logs Progress - Provides detailed migration logs
- Continues Operation - Doesn't block the API from running
Target: All orders created before December 3, 2025, 12:28:31 AM Action: Automatically assigned to Base chain (chainId: 8453) Status: Non-blocking (runs in background on first health check)
-
Health Check (Every 5 minutes)
- Verifies API availability
- Runs pending migrations
-
Metrics Sync (Every 30 minutes)
- Fetches order counts from smart contracts
- Tracks total volume across chains
- Stores metrics in database
-
Order History Sync (Every 30 minutes)
- Syncs blockchain events to database
- Updates transaction status
- Processes new orders from contracts
-
Token Volume Sync (Every 30 minutes)
- Calculates total USD value across all chains
- Converts to NGN (Nigerian Naira)
- Updates supported token list
- Base: 168 orders (141 successful, 23 failed)
- Lisk: 1 order (1 successful, 0 failed)
- Celo: 4 orders (3 successful, 1 failed)
- Total: 173 orders
- β All required fields validated before processing
- β Address checksums verified on blockchain transactions
- β Transaction hash validation against blockchain
- β Request ID uniqueness checked to prevent duplicate orders
When creating orders, the system implements these security measures:
-
Database Connection Verification
- Every order operation connects to MongoDB first
- Ensures no data is processed without database access
- Validates connection before any write operation
-
Request ID Validation
- Each order has a unique
requestId - Prevents duplicate order processing
- Checked before order creation
- Each order has a unique
-
User Address Validation
- All orders require valid
userAddress - Address is lowercase normalized for consistency
- Enables proper user transaction history tracking
- All orders require valid
-
Transaction Hash Verification
transactionHashis validated against blockchain- Ensures payment was actually made on-chain
- Prevents fraudulent orders without blockchain confirmation
-
Chain Information Validation
chainIdmust be valid (8453, 1135, or 42220)chainNamemust match chainId- Ensures order is recorded on correct blockchain
-
Data Integrity
- All required fields validated before saving
- Schema validators run on every update
- Type checking for amounts and identifiers
- Automatic timestamps for audit trail
-
Error Handling & Logging
- All operations logged for audit trail
- Errors caught and logged without exposing sensitive data
- Failed operations don't partially update database
- Rollback on validation failures
β οΈ Subject to RPC provider rate limits- π Currently experiencing occasional "over rate limit" errors
- β Errors are logged but don't stop operation
- β Cross-origin requests properly handled
- β Preflight requests supported
- β Frontend can safely communicate with backend
Problem: "Over rate limit" errors when fetching token details
Impact: Temporary delays in token sync, doesn't affect transactions
Solution: Uses multiple RPC providers, retries automatically
Problem: Email service timeout on startup
Impact: Notifications may not send initially
Solution: Service continues running, email can be reconfigured
MONGODB_URI=mongodb+srv://...
NEXT_PUBLIC_RPC_BASE=https://...
NEXT_PUBLIC_RPC_LISK=https://...
NEXT_PUBLIC_RPC_CELO=https://...
VTPASS_API_KEY=...- Code Pushed β GitHub repository updated
- Build Starts β Dependencies installed, app compiled
- Server Starts β Node.js server begins running
- Migrations Run β Database updates happen automatically
- Cron Jobs Start β Sync services begin scheduled tasks
- Ready β API accepts requests
Configure in Render dashboard:
- Health Check Path:
/api/health - Check Interval: Every 5 minutes
- Timeout: 10 seconds
Paycrypt-backend/
βββ app/
β βββ api/
β βββ airtime/route.js # Airtime purchase endpoint
β βββ internet/route.js # Internet purchase endpoint
β βββ electricity/route.js # Electricity purchase endpoint
β βββ tv/route.js # TV subscription endpoint
β βββ health/route.js # Health check + migration
β βββ history/route.js # Transaction history
βββ lib/
β βββ migrations.js # Automatic migration logic
β βββ order-service.js # Order CRUD operations
β βββ vtpassService.js # VTPass API integration
β βββ cors.js # CORS handling
βββ models/
β βββ order.js # MongoDB Order schema
βββ utils/
β βββ errorHandler.js # Error handling utilities
βββ db/
β βββ index.js # MongoDB connection
βββ config/
β βββ index.js # Configuration
βββ next.config.js # Next.js configuration
βββ README.md # This file
Q: Orders not appearing in history?
- Check that
chainIdandchainNameare being sent correctly - Verify user address is lowercase
Q: Payment failing on specific chain?
- Verify stablecoin balance on that chain
- Check token approval amount
- Ensure chain is selected correctly
Q: Migration not running?
- Call
/api/healthendpoint to trigger manually - Check Render logs for migration status
Q: RPC rate limit errors?
- These are temporary and don't affect transactions
- Check the logs - errors will show "over rate limit"
- System automatically retries
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env.local
# Run development server
npm run dev
# Build for production
npm run build
# Start production server
npm start# Health check
curl http://localhost:3000/api/health
# Get transaction history
curl "http://localhost:3000/api/history?userAddress=0x..."
# Test airtime purchase (POST)
curl -X POST http://localhost:3000/api/airtime \
-H "Content-Type: application/json" \
-d '{ ... }'- Add more blockchain networks
- Support additional payment tokens
- Implement transaction retry logic
- Add webhook notifications
- Enhanced analytics tracking
- Multi-language support
This project is proprietary. All rights reserved.
Last Updated: December 9, 2025
System Status: β
All 3 chains operational | β
173 orders processed | β
Migrations automated
Support: support@paycrypt.org