🌐 README на русском | 🌐 README in English
A self-hosted crypto payment gateway. Merchants can accept payments in several cryptocurrencies, create invoices, watch confirmations happen on-chain in real time, and withdraw the money they collected. There is a dashboard for people and a REST API for code.
Status: archived. The project is no longer maintained and the hosted version (payproof.org) has been shut down.
A merchant signs up, creates a shop, and gets an API key. From there they can make invoices either by hand in the dashboard or from their own backend through the API. The customer pays to an address from a managed wallet pool. A background monitor watches each blockchain, matches incoming transactions to open invoices, and marks an invoice as paid once the payment is confirmed. Later the merchant can withdraw their balance on-chain.
- Payments on five chains: Ethereum, BSC, Tron, Bitcoin, Litecoin, plus USDT (ERC-20, BEP-20, TRC-20)
- Hosted invoice pages with fiat to crypto conversion at the moment the invoice is created
- Real-time payment monitor with per-chain watchers, adaptive polling and provider fallback
- Wallet pool with private keys encrypted at rest (AES-256-GCM)
- On-chain withdrawals with gas estimation and commission accounting
- Merchant dashboard: shops, invoices, balances, withdrawals
- Admin panel: users, shops, stats, commission settings
- REST API for merchants, protected by an API key and secret
- No-code integration for Tilda
- Auth with JWT and bcrypt, email verification, rate limiting, security headers
- Two languages: English and Russian
- Next.js 16 (App Router) and React 19, TypeScript
- Chakra UI, Framer Motion, Three.js
- PostgreSQL with Prisma ORM
- ethers.js, TronWeb, bitcoinjs-lib for blockchain work
- JWT and bcrypt for auth
- i18next for translations, Nodemailer for email
src/
app/
api/ internal API (auth, shops, invoices, withdrawal, admin)
dev-api/ public merchant API (API key auth) and Tilda callbacks
lib/
blockchain/ RPC providers, exchange rates, chain helpers
monitor/ per-chain payment watchers and the payment processor
wallet/ wallet pool, balances, transactions
services/ withdrawal service
encryption.ts AES-256-GCM for wallet keys
components/ shared UI
locales/ en and ru translations
scripts/ payment monitor, wallet seeding, key encryption, manual tx checks
prisma/ schema and migrations
You need Node.js 20 or newer and a PostgreSQL database.
1. Install dependencies
npm install2. Set up the environment file
cp .env.example .envOpen .env and fill in at least DATABASE_URL, JWT_SECRET, WALLET_ENCRYPTION_KEY and your pool wallets. You can generate the two secrets like this:
openssl rand -base64 32 # for JWT_SECRET
openssl rand -hex 32 # for WALLET_ENCRYPTION_KEYEvery variable is explained in .env.example. The RPC provider keys (Infura, Alchemy, TronGrid, BlockCypher, CoinGecko) are optional. Without them the app falls back to public endpoints.
3. Prepare the database
npx prisma generate
npx prisma migrate deploy4. Seed the wallet pool (uses the POOL_* values from .env)
npx tsx --env-file .env scripts/seed-pool-wallets.ts5. Start the app and the monitor
npm run dev # app on http://localhost:3000
npm run monitor # background payment monitor, in a second terminalIn the dashboard: register, verify your email, create a shop, then create invoices and share the hosted payment link with your customers. The dashboard also shows balances and lets you request withdrawals.
Through the API: open a shop's page to get its API key and secret. Every request to the merchant API sends them in headers:
X-API-Key: your-api-key
X-API-Secret: your-api-secret
Create an invoice:
curl -X POST http://localhost:3000/dev-api/invoices \
-H "X-API-Key: your-api-key" \
-H "X-API-Secret: your-api-secret" \
-H "Content-Type: application/json" \
-d '{
"amount": 10.00,
"currency": "USD",
"description": "Order #1234",
"callbackUrl": "https://your-site.com/webhook",
"successUrl": "https://your-site.com/thanks",
"externalId": "order-1234"
}'The response includes the invoice and a link to its hosted payment page. When the payment is confirmed, PayProof sends a webhook to your callbackUrl. You can also list invoices with GET /dev-api/invoices and check a single one with GET /dev-api/invoices/{id}.
The in-app documentation page has the full API reference, including the webhook signature check.
- Wallet private keys are encrypted at rest with AES-256-GCM and are never committed. See
.env.example. - Merchant API requests are checked with an API key and secret using a timing-safe comparison.
- Passwords are hashed with bcrypt and JWTs are verified at the edge.





