A reliable payment processing service built with NestJS and integrated with PayHere payment gateway. This service handles payment initiation, status tracking, and webhook processing.
Before you start, make sure you have:
- Node.js (version 16 or higher)
- npm or yarn package manager
- A PayHere merchant account (Sign up here)
- PostgreSQL database (or NeonDB)
-
Copy the example environment file:
cp .env.example .env
-
Configure your
.envfile with the following variables:# Application Configuration NODE_ENV=development PORT=3000 API_PREFIX=api/v1 # Database Configuration DATABASE_URL="postgresql://user:password@host/database?sslmode=require" # Database Pool Settings DB_POOL_MIN=2 DB_POOL_MAX=10 DB_CONNECTION_TIMEOUT=20000 DB_IDLE_TIMEOUT=30000 # PayHere Configuration PAYHERE_MERCHANT_ID=your_merchant_id PAYHERE_MERCHANT_SECRET=your_merchant_secret PAYHERE_MODE=sandbox # Use 'live' for production PAYHERE_API_URL=https://sandbox.payhere.lk/pay/checkout # Security & Rate Limiting CORS_ORIGIN=http://localhost:3000,http://localhost:3001 RATE_LIMIT_TTL=60 RATE_LIMIT_MAX=100 # Logging LOG_LEVEL=debug LOG_FORMAT=json # Health Check HEALTH_CHECK_ENABLED=true HEALTH_CHECK_DATABASE_ENABLED=true # Webhook Configuration WEBHOOK_TIMEOUT=30000 WEBHOOK_RETRY_ATTEMPTS=3 WEBHOOK_RETRY_DELAY=1000
-
Install dependencies:
npm install
-
Setup the database (Generate client, migrate, and seed):
npm run db:setup
Start the development server:
npm run start:devThe service will be available at http://localhost:3000
For production:
npm run build
npm run start:prod- URL:
/payments - Method:
POST - Summary: Create a new payment
- Headers:
idempotency-key(optional): Unique key to prevent duplicate payments
- Body:
{ "bookingId": "BOOKING-001", "amount": 1500.00, "currency": "LKR", "userId": "user-123", "userEmail": "user@example.com", "userPhone": "0771234567" }
- URL:
/payments/:id - Method:
GET - Summary: Get payment details by UUID
- URL:
/webhooks/payhere - Method:
POST - Summary: Receives payment notifications from PayHere
- Headers:
x-payhere-signature: HMAC-SHA256 signature for verification
- URL:
/webhooks/payhere/test - Method:
POST - Summary: Test endpoint that bypasses signature verification
const response = await fetch('http://localhost:3000/payments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'idempotency-key': 'unique-request-id'
},
body: JSON.stringify({
bookingId: 'BOOKING-123',
amount: 1000.00,
currency: 'LKR',
userId: 'user-123',
userEmail: 'customer@example.com',
userPhone: '0771234567'
})
});
const data = await response.json();
// Use data to redirect to PayHereRun unit tests:
npm run testRun e2e tests:
npm run test:e2e- PayHere Documentation: https://support.payhere.lk/
- NestJS Documentation: https://docs.nestjs.com/