A payment processing service enabling automated systems to receive cryptocurrency payments, convert between currencies, and automatically forward funds to configured addresses.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Frontend │ │ API │ │ Backend │
│ (VueJS) │◄───►│ (Go) │◄───►│ (Go) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ PostgreSQL │ │ Blockchains│
└─────────────┘ │ (BTC,LTC,SOL)
└─────────────┘
- BTC (Bitcoin) - 4 confirmations
- LTC (Litecoin) - 4 confirmations
- SOL (Solana) - 4 confirmations
Returns list of available tickers with metadata.
Response 200:
{
"results": [
{"ticker": "btc", "name": "Bitcoin", "min_tx_amount": 0.0001, "min_fees": 0.0001, "decimals": 8}
]
}Returns information for a specific ticker.
Response 200:
{
"result": {"ticker": "btc", "name": "Bitcoin", "min_tx_amount": 0.0001, "min_fees": 0.0001, "decimals": 8}
}Converts between tickers or ticker to fiat.
Response 200:
{
"result": {
"ticker": {"from": "btc", "to": "eur"},
"amount": {"from": 1, "to": 80000}
}
}Generates a derived payment address for a ticker.
Request Body:
{
"outputs": [{"address": "x", "percentage": 40}, {"address": "y", "percentage": 60}],
"callback_url": "https://example.com/callback-and-uid"
}Response 201:
{
"result": {
"payment_address": "z",
"payment_uid": "ab67-cd69-ef420-gh88",
"ticker": "btc",
"inputs": {"minimum_coin": 0.0001},
"outputs": [{"address": "x", "percentage": 40}, {"address": "y", "percentage": 60}],
"callback_url": "https://example.com/callback-and-uid"
}
}Returns payment status and history.
Response 200:
{
"result": {
"payment_address": "z",
"payment_uid": "ab67-cd69-ef420-gh88",
"ticker": "btc",
"inputs": {
"minimum_coin": 0.0001,
"logs": [{"amount": 0.02, "confirmations": 4, "status": "received"}]
},
"outputs": [
{"address": "x", "percentage": 40, "logs": [{"amount": 0.008, "confirmations": 4, "status": "sent"}]},
{"address": "y", "percentage": 60, "logs": [{"amount": 0.012, "confirmations": 4, "status": "sent"}]}
],
"callback_url": "https://example.com/callback-and-uid"
}
}| Column | Type | Description |
|---|---|---|
| id | SERIAL PRIMARY KEY | |
| ticker | VARCHAR(10) UNIQUE | btc, ltc, sol |
| name | VARCHAR(100) | Bitcoin, Litecoin, Solana |
| min_tx_amount | DECIMAL(20,8) | Minimum transaction |
| min_fees | DECIMAL(20,8) | Network fees |
| decimals | INT | Decimal places |
| enabled | BOOLEAN | Is ticker active |
| created_at | TIMESTAMP | Creation time |
| Column | Type | Description |
|---|---|---|
| id | SERIAL PRIMARY KEY | |
| ticker | VARCHAR(10) | FK to tickers |
| payment_uid | UUID UNIQUE | Payment identifier |
| payment_address | VARCHAR(255) | Derived address |
| callback_url | TEXT | Callback URL |
| minimum_coin | DECIMAL(20,8) | Min expected amount |
| status | VARCHAR(20) | pending/completed |
| created_at | TIMESTAMP | Creation time |
| Column | Type | Description |
|---|---|---|
| id | SERIAL PRIMARY KEY | |
| payment_address_id | INT | FK to payment_addresses |
| address | VARCHAR(255) | Output address |
| percentage | DECIMAL(5,2) | Split percentage (0-100) |
| created_at | TIMESTAMP | Creation time |
| Column | Type | Description |
|---|---|---|
| id | SERIAL PRIMARY KEY | |
| payment_address_id | INT | FK to payment_addresses |
| output_index | INT NULL | NULL for input |
| amount | DECIMAL(20,8) | Transaction amount |
| confirmations | INT | Number of confirmations |
| tx_hash | VARCHAR(255) | Transaction hash |
| status | VARCHAR(20) | received/confirmed/sent |
| created_at | TIMESTAMP | Creation time |
Each blockchain implements a common interface:
type BlockchainWallet interface {
GetAddressFromSeed(seed []byte, index uint32) (string, error)
CreatePaymentAddress(paymentUID string) (string, error)
ValidateAddress(address string) bool
GetTransactions(address string) ([]Transaction, error)
SendTransaction(from string, to string, amount decimal.Decimal) (string, error)
GetConfirmations(txHash string) (int, error)
}- User generates payment address via API
- Backend watcher monitors blockchain for incoming transactions
- When funds received, callback URL is notified
- After 4 confirmations, funds are forwarded to output addresses
- Output logs are updated with forwarding status
Environment variables for sensitive data:
DATABASE_URLBTC_RPC_URL,BTC_RPC_USER,BTC_RPC_PASS,BTC_WALLET_ADDRESSLTC_RPC_URL,LTC_RPC_USER,LTC_RPC_PASS,LTC_WALLET_ADDRESSSOL_RPC_URL,SOL_WALLET_ADDRESSFIAT_API_URL(e.g., CoinGecko)LOG_LEVEL(DEBUG, INFO, WARN, ERROR)
BTC_RPC_URL=https://bitcoin-mainnet.gateway.tatum.io
BTC_RPC_USER=
BTC_RPC_PASS=
LTC_RPC_URL=https://litecoin-mainnet.gateway.tatum.io
LTC_RPC_USER=
LTC_RPC_PASS=
SOL_RPC_URL=https://solana-mainnet.gateway.tatum.io
- Single wallet architecture: All funds pool to one wallet per chain
- No multisig: Single point of failure for fund access
- No transaction limits: Any amount can be forwarded
- Irreversible transactions: Blockchain transactions cannot be reversed
- Use wallet with limited funds (hot wallet principle)
- Implement monitoring/alerting for unusual activity
- Consider offline storage for large amounts
- Regular audit of forwarding transactions
- Test with small amounts first
Note: Free tier provides 5 requests/minute with no registration. Sufficient for low-volume testing with real funds.
- BTC JSON-RPC: https://bitcoin-mainnet.gateway.tatum.io
- BTC REST: https://bitcoin-mainnet.gateway.tatum.io/rest
- LTC JSON-RPC: https://litecoin-mainnet.gateway.tatum.io
- LTC REST: https://litecoin-mainnet.gateway.tatum.io/rest
- JSON-RPC: https://solana-mainnet.gateway.tatum.io
- FreeRPC.com: https://freerpc.com/bitcoin (5 req/min, no signup)
- PublicNode: https://bitcoin-rpc.publicnode.com
- Blockstream: https://blockstream.info/api (read-only, rate limited)
- FreeRPC.com: https://freerpc.com/litecoin (5 req/min, no signup)
- PublicNode: https://litecoin-rpc.publicnode.com
- Solana Foundation: https://api.mainnet-beta.solana.com (rate limited, no SLA)
- PublicNode: https://solana-rpc.publicnode.com
- NoLimitNodes Free: https://api.nolimitnodes.com/rpc (10 req/sec, requires API key)
- dRPC: https://solana.drpc.org (free tier available)
Warning: Free RPC tier is rate-limited and not suitable for production payment processing with real funds.
For mainnet deployment with real funds, consider:
- Tatum Paid Tier: Higher rate limits, SLA guarantee
- QuickNode: Enterprise-grade reliability
- Helius: Solana-focused with enhanced APIs
- Chainstack: Multi-chain support with dedicated nodes
Rate limits for free tiers:
- Tatum: 5 req/min
- Solana Foundation: 100 req/10sec per IP
To respect free tier rate limits (5 req/min), all wallet implementations include an RPC cache with 15-second minimum gap between calls.
- Minimum gap: 15 seconds between RPC calls to same endpoint
- Transaction cache TTL: 60 seconds
- Confirmation cache TTL: 30 seconds
- Strict mode: Enabled by default (enforces minimum gap)
GetTransactions(): Cached per address, 60s TTLGetConfirmations(): Cached per tx hash, 30s TTLSendTransaction(): Invalidates sender's transaction cache- All cache operations respect the 15-second rate limit gap
internal/blockchain/cache.go: Core cache implementation- Separate cache instances per wallet (BTC, LTC, SOL)
- Thread-safe with sync.RWMutex
Cache exposes GetStats() method returning:
{
"total_entries": 10,
"active_entries": 8,
"min_gap_seconds": 15,
"strict_mode": true
}- Docker Compose for orchestration
- Cloudflare Tunnel for public exposure
- PostgreSQL for persistence
Structured JSON logging with:
- Request/response tracking
- Blockchain event monitoring
- Error tracking with stack traces
- Performance metrics