A professional demo wallet application showcasing cryptocurrency payment integration using NowPayments API. Built with Next.js 15+, TypeScript, MongoDB, and NextAuth.
- User Authentication: Secure registration and login system using NextAuth with credentials
- Wallet Balance Management: Real-time balance tracking for each user
- Cryptocurrency Payments: Integration with 100+ cryptocurrencies via NowPayments
- Real-time Payment Estimation: Live conversion rates from USD to selected cryptocurrency
- Payment Processing: Seamless redirect to NowPayments sandbox for payment completion
- IPN Webhook Handler: Automatic balance updates upon successful payments
- Payment History: Comprehensive transaction history with filtering capabilities
- Payment Query System: Check any payment status directly from NowPayments API
- Dashboard Analytics: Visual statistics for total, successful, failed, and pending payments
- Frontend: Next.js 16.1.3 (App Router), React 19, TypeScript
- UI Components: ShadCN UI, Radix UI, Tailwind CSS
- Authentication: NextAuth v5 with JWT strategy
- Database: MongoDB with Mongoose ODM
- Payment Gateway: NowPayments API (Sandbox)
- Forms: React Hook Form with Zod validation
- Notifications: Sonner toast notifications
my-app/
βββ app/
β βββ (auth)/ # Authentication routes
β β βββ login/ # Login/Register page
β β βββ layout.tsx # Auth layout
β βββ (dashboard)/ # Protected routes
β β βββ dashboard/ # Main dashboard
β β βββ query-payment/ # Payment query page
β β βββ layout.tsx # Dashboard layout with nav
β βββ api/
β β βββ auth/
β β β βββ [...nextauth]/ # NextAuth handlers
β β β βββ register/ # User registration
β β βββ nowpayments/
β β β βββ currencies/ # Get available currencies
β β β βββ estimate/ # Payment estimation
β β β βββ create-payment/ # Create payment
β β β βββ payment-status/ # Query payment
β β β βββ webhook/ # IPN callback handler
β β βββ wallet/
β β βββ balance/ # Get user balance
β β βββ payments/ # Get payment history
β β βββ stats/ # Get payment statistics
β βββ layout.tsx # Root layout
β βββ page.tsx # Root redirect
βββ components/
β βββ add-balance-dialog.tsx # Add balance modal
β βββ ui/ # ShadCN UI components
βββ lib/
β βββ auth.ts # NextAuth configuration
β βββ db.ts # MongoDB connection
β βββ nowpayments.ts # NowPayments API client
β βββ models/
β βββ User.ts # User schema
β βββ Payment.ts # Payment schema
βββ .env # Environment variables
{
email: string (unique, required)
password: string (hashed, required)
name: string (required)
balance: number (default: 0)
createdAt: Date
updatedAt: Date
}{
userId: ObjectId (ref: User)
amount: number (USD amount)
currency: string (crypto currency code)
status: enum (waiting | confirming | confirmed | sending | partially_paid | finished | failed | refunded | expired)
nowPaymentsData: object (full payment data from NowPayments)
webhookReceived: boolean
webhookData: object (IPN callback data)
createdAt: Date
updatedAt: Date
}User Dashboard β Click "Add Balance" β Opens Modal
1. User enters USD amount (e.g., $75)
2. User clicks "Continue to Payment"
3. System creates invoice via NowPayments API
4. Invoice record saved to MongoDB with status "waiting"
1. User redirected to NowPayments hosted payment page
2. User selects preferred cryptocurrency (BTC, ETH, USDT, etc.)
3. System shows real-time conversion rate
4. User completes payment (sends crypto to provided address)
5. NowPayments processes the transaction on blockchain
1. NowPayments sends IPN to /api/nowpayments/webhook
2. System verifies signature using HMAC-SHA512
3. Payment status updated in database (waiting β finished)
4. REAL payment ID updated (different from invoice ID)
5. If status = "finished", user balance credited automatically
6. User redirected back to dashboard
IMPORTANT FOR LOCAL DEVELOPMENT:
- Webhooks require a public URL (not localhost)
- Use ngrok to expose localhost:
ngrok http 3000 - Or use "Sync Payments" button to manually update status
1. Dashboard refreshes (or user clicks "Sync Payments")
2. New balance displayed ($0 β $75)
3. Payment appears in history with "Completed" status
4. Payment ID updated to match NowPayments dashboard
IPN (Instant Payment Notification) is NowPayments' webhook system that sends real-time payment updates to your server.
-
Configuration: Set IPN callback URL in payment creation
ipn_callback_url: `${NEXT_PUBLIC_APP_URL}/api/nowpayments/webhook` -
Signature Verification: Every IPN request includes a signature header
const signature = request.headers.get('x-nowpayments-sig'); const isValid = verifyIPNSignature(signature, requestBody);
-
Signature Calculation:
HMAC-SHA512(requestBody, NOWPAYMENTS_IPN_SECRET)
-
Security: Without valid signature, webhook is rejected (prevents unauthorized balance credits)
waiting β confirming β confirmed β sending β finished β
β
failed β
- waiting: Payment created, awaiting user to send crypto
- confirming: Transaction detected on blockchain, waiting confirmations
- confirmed: Transaction confirmed on blockchain
- sending: Payment being processed by NowPayments
- finished: Payment complete, balance credited
- failed: Payment failed
- expired: User didn't pay within time limit
- partially_paid: User sent less than required amount
- β Signature verification for security (HMAC-SHA512)
- β Automatic balance crediting on "finished" status
- β Idempotent processing (won't credit balance twice)
- β Real payment ID updates (different from invoice ID)
- β Lookup by order_id (more reliable than payment_id)
- β Full payment data logging
- β Error handling with graceful degradation
Since webhooks don't work on localhost, we've added:
- β "Sync Payments" button on dashboard
- β Manually queries NowPayments API for status
- β Updates database and credits balance
- β Works with both invoice IDs and payment IDs
- β Fallback lookup by order_id if payment_id not found
git clone <repository-url>
cd my-app
pnpm installCopy .env.example to .env and fill in your credentials:
cp .env.example .envRequired variables:
MONGODB_URL: Your MongoDB connection stringNEXTAUTH_SECRET: Generate withopenssl rand -base64 32NOWPAYMENTS_API_KEY: From NowPayments dashboardNOWPAYMENTS_IPN_SECRET: From NowPayments dashboardNEXT_PUBLIC_APP_URL: Your application URL
- Sign up at NowPayments Sandbox
- Navigate to Settings β API Keys
- Copy your API Key
- Navigate to Settings β IPN Settings
- Copy your IPN Secret Key
pnpm devUse ngrok or similar to expose your local server:
ngrok http 3000Your webhook URL will be:
https://your-ngrok-url.ngrok.io/api/nowpayments/webhook
-
Register Account
- Navigate to http://localhost:3000
- Click "Create Account"
- Fill in name, email, password
- Auto-login after registration
-
Add Balance
- Click "Add Balance" on dashboard
- Enter amount in USD
- Select cryptocurrency (searchable dropdown)
- View real-time conversion estimate
- Click "Continue to Payment"
- Confirm payment details
- Redirected to NowPayments
-
Complete Payment (Sandbox)
- In sandbox, payment completes automatically
- Redirected back to dashboard
- Balance updated automatically via webhook
-
View History
- All payments shown in history table
- Filter by status
- View payment details (date, amount, crypto, status)
-
Query Payment
- Navigate to "Query Payment"
- Enter payment ID
- View full payment details from NowPayments
POST /api/auth/register- Register new userPOST /api/auth/[...nextauth]- NextAuth handlers
GET /api/wallet/balance- Get user balanceGET /api/wallet/payments- Get payment history (with filters)GET /api/wallet/stats- Get payment statistics
GET /api/nowpayments/currencies- Get available cryptocurrenciesGET /api/nowpayments/estimate- Get payment estimatePOST /api/nowpayments/create-payment- Create new paymentGET /api/nowpayments/payment-status- Query payment statusPOST /api/nowpayments/webhook- IPN callback handler
NowPayments sandbox automatically completes payments for testing:
- Create payment
- Payment status automatically transitions: waiting β confirming β finished
- Webhook triggered automatically
- Balance credited
- User registration
- User login
- Add balance flow
- Currency selection and search
- Payment estimation
- Payment creation
- Redirect to NowPayments
- Webhook processing
- Balance update
- Payment history
- Status filtering
- Payment query
- User logout
- Authentication: JWT-based session management
- Password Hashing: bcrypt with salt rounds
- IPN Verification: HMAC-SHA512 signature validation
- Protected Routes: Server-side authentication checks
- Input Validation: Zod schema validation
- SQL Injection Prevention: Mongoose ODM parameterized queries
- XSS Protection: React automatic escaping
- Large, prominent display of USD balance
- Add balance button
- Gradient background for visual appeal
- Total Payments
- Successful Payments (green)
- Pending Payments (yellow)
- Failed Payments (red)
- Date and time
- Amount (USD and crypto)
- Cryptocurrency type
- Payment ID (truncated)
- Status badge
- Filter by status
- Sortable columns
- MongoDB Atlas cluster
- NowPayments production account
- Domain with HTTPS (required for webhooks)
Update .env for production:
- Use production MongoDB URL
- Use production NowPayments API URL
- Set production domain for callbacks
- Ensure HTTPS for webhook URL
Vercel (Recommended):
vercel --prodDocker:
docker build -t crypto-wallet .
docker run -p 3000:3000 --env-file .env crypto-wallet- Update NowPayments IPN settings with production webhook URL
- Test payment flow end-to-end
- Monitor webhook logs
- Set up error tracking (Sentry, etc.)
- Webhook Implementation: Fully documented with signature verification
- Payment Flow: Complete end-to-end implementation with callbacks
- Security: Production-ready with proper authentication and validation
- Error Handling: Comprehensive error handling throughout
- Logging: Console logs for debugging webhook and payment flows
- Database Design: Normalized schema with proper indexing
- API Design: RESTful endpoints with proper status codes
- Code Quality: TypeScript strict mode, proper interfaces, clean architecture
- No email verification
- No 2FA authentication
- No withdrawal functionality
- Sandbox only (not production-ready without additional security)
- No rate limiting
- No payment amount limits
- Check NOWPAYMENTS_IPN_SECRET is set correctly
- Verify webhook URL is HTTPS in production
- Check ngrok is running for local development
- Review webhook logs in NowPayments dashboard
- Check webhook logs in server console
- Verify payment status is "finished"
- Check database for payment record
- Ensure no duplicate payment processing
- Verify NOWPAYMENTS_API_KEY is correct
- Check API rate limits
- Verify amount meets minimum requirements
- Check selected currency is available
- NowPayments API Documentation
- NowPayments Sandbox
- Next.js Documentation
- NextAuth.js Documentation
- MongoDB Documentation
This is a demo application for educational purposes.
Built with professional standards following senior software engineering practices:
- Clean architecture
- Type safety
- Error handling
- Security best practices
- Comprehensive documentation
- Production-ready code structure
Note: This is a demonstration application. For production use, implement additional security measures, monitoring, and compliance requirements specific to financial applications.