Quick Start
Get PayWarden running locally in under 3 minutes.
Prerequisites
- Docker & Docker Compose
- A TRON wallet (for your hot wallet address)
- A TronGrid API key (free at trongrid.io)
1. Clone and configure
bash
git clone https://github.com/paywarden/paywarden
cd paywarden
cp .env.example .envEdit .env with your values:
bash
# Generate a secure 32-byte hex key
openssl rand -hex 32dotenv
# .env
VAULT_KEY=<your-32-byte-hex-key> # encrypts your seed phrase
API_KEY=<your-api-key> # authenticates your backend calls
TRON_FULL_HOST=https://nile.trongrid.io # use mainnet for production
TRONGRID_API_KEY=<your-trongrid-key>
HOT_WALLET_ADDRESS=<your-tron-address> # where swept funds go
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/paywarden
REDIS_URL=redis://redis:63792. Start the gateway
bash
docker compose up -dThis starts PostgreSQL, Redis, and PayWarden. Wait ~10 seconds for services to initialize.
3. Initialize your wallet
bash
curl -X POST http://localhost:3000/api/v1/wallet/init \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{}'Save the mnemonic phrase that's returned — this is your backup. It will never be shown again.
json
{
"mnemonic": "abandon ability able about above absent absorb abstract ...",
"address": "TXxx...your-first-address"
}Back up your mnemonic
Store your mnemonic phrase offline in a secure location. It's the only way to recover your funds if the server is lost.
4. Create a payment order
bash
curl -X POST http://localhost:3000/api/v1/payments \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"amount": "10.00",
"currency": "USDT",
"external_id": "order_123",
"webhook_url": "https://your-backend.com/webhooks/paywarden"
}'Response:
json
{
"id": "ord_abc123",
"status": "pending",
"amount": "10.00",
"currency": "USDT",
"address": "TYxx...unique-payment-address",
"expires_at": "2025-01-01T01:00:00Z",
"checkout_url": "http://localhost:3000/checkout/ord_abc123"
}5. Customer pays
Share the address or embed the checkout_url in an iframe:
html
<iframe
src="https://pay.yourdomain.com/checkout/ord_abc123"
width="400"
height="600"
frameborder="0"
/>6. Receive webhook confirmation
When payment is confirmed, PayWarden POSTs to your webhook_url:
json
{
"event": "payment.confirmed",
"order_id": "ord_abc123",
"external_id": "order_123",
"amount": "10.00",
"currency": "USDT",
"tx_hash": "0xabc...def",
"confirmed_at": "2025-01-01T00:05:00Z"
}Verify the signature:
typescript
import crypto from 'crypto'
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}
// In your webhook handler:
const sig = req.headers['x-paywarden-signature']
if (!verifyWebhook(req.rawBody, sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature')
}Next steps
- Configuration — all environment variables explained
- Webhooks — webhook events and retry logic
- Security Hardening — production deployment checklist
- Admin Dashboard — monitor orders and revenue