4.5 KiB
NOWPayments IPN Listener
A TypeScript Express application for receiving and processing Instant Payment Notifications (IPN) from NOWPayments.
Features
- ✅ Secure IPN signature validation using HMAC SHA512
- ✅ TypeScript for type safety
- ✅ Handles all NOWPayments payment statuses
- ✅ MySQL/MariaDB database integration
- ✅ Automatic payment processing: moves finished payments from
pending_orderstosales - ✅ Transaction-safe database operations
- ✅ Error handling and logging
Setup
1. Install Dependencies
npm install
2. Configure Environment Variables
Copy .env.example to .env and fill in your NOWPayments IPN Secret Key:
cp .env.example .env
Edit .env and configure:
NOWPayments IPN Secret Key:
- Go to NOWPayments Dashboard → Store Settings → IPN Secret Key
- Generate a new key if you don't have one
- Add it to the
.envfile
Database Configuration:
- Set your MySQL/MariaDB connection details:
DB_HOST- Database host (default: localhost)DB_PORT- Database port (default: 3306)DB_USER- Database usernameDB_PASSWORD- Database passwordDB_NAME- Database name (default: cbd420)
3. Build the Project
npm run build
4. Run the Server
Development mode (with auto-reload):
npm run dev
Production mode:
npm start
The server will start on port 3000 (or the port specified in your .env file).
Endpoints
POST /ipn
Receives IPN notifications from NOWPayments. This endpoint:
- Validates the request signature
- Processes payment status updates
- Returns 200 OK to acknowledge receipt
GET /health
Health check endpoint to verify the server is running.
IPN Callback URL Setup
When creating a payment via the NOWPayments API, include the ipn_callback_url parameter:
{
"price_amount": 100,
"price_currency": "usd",
"pay_currency": "btc",
"ipn_callback_url": "https://yourdomain.com/ipn",
// ... other parameters
}
Payment Statuses
The listener handles the following payment statuses:
waiting- Payment is waitingconfirming- Payment is being confirmed on blockchainconfirmed- Payment confirmed on blockchainsending- Payment is being sentpartially_paid- Payment partially receivedfinished- Payment completed successfullyfailed- Payment failedrefunded- Payment refundedexpired- Payment expired
Database Integration
The application automatically integrates with your MySQL/MariaDB database. When a payment status is finished, the system will:
- Validate the payment - Check if the payment exists in
pending_orders - Create a sale record - Insert the payment into the
salestable - Remove pending order - Delete the record from
pending_orders
All operations are performed within a database transaction to ensure data consistency.
Database Schema
The application expects the following tables (as defined in cbd420(1).sql):
-
pending_orders- Stores pending payment orderspayment_id(unique) - NOWPayments payment IDorder_id(unique) - Your order IDdrop_id- Reference to drops tablebuyer_id- Reference to buyers tablesize- Order sizeprice_amount- Payment amountprice_currency- Payment currency
-
sales- Stores completed salesdrop_id- Reference to drops tablebuyer_id- Reference to buyers tablesize- Sale sizepayment_id- NOWPayments payment ID
Payment Processing Flow
- Payment is created → Record inserted into
pending_orders - IPN notification received → Signature validated
- Payment status
finished→ Record moved frompending_orderstosales - Transaction committed → Payment processing complete
The system includes idempotency checks to prevent duplicate processing if the same IPN notification is received multiple times.
Security
- All IPN requests are validated using HMAC SHA512 signature verification
- Invalid signatures are rejected with 400 Bad Request
- The IPN secret key should never be committed to version control
Testing
You can test the IPN endpoint using tools like:
- Postman
- curl
- NOWPayments test payments
Example curl command (with test signature):
curl -X POST http://localhost:3000/ipn \
-H "Content-Type: application/json" \
-H "x-nowpayments-sig: your_signature_here" \
-d '{"payment_id":"test123","payment_status":"waiting","price_amount":100,"price_currency":"usd"}'
License
ISC