A full-stack payment integration system built with Node.js, Stripe, PostgreSQL, and React.
- Overview
- Architecture
- Features
- Quick Start
- Environment Variables
- API Reference
- Testing
- Stripe Test Cards
- Deployment
PayFlow is a production-ready payment processing backend and frontend that demonstrates a real-world Stripe integration. It handles the full payment lifecycle β from user registration and order creation, through payment intent generation and webhook processing, to refunds and admin reporting.
+-----------------+ +-----------------+ +----------------+
| React Client | ---> | Node.js API | ---> | PostgreSQL |
| (localhost:3001)| | (localhost:8080)| | (db) |
+-----------------+ +-----------------+ +----------------+
|
v
+-----------------+
| Stripe API |
| + Webhooks |
+-----------------+
| Service | Port | Description |
|---|---|---|
| API | 8080 |
Node.js / Express REST API |
| Client | 3001 |
React frontend |
| Database | 5432 |
PostgreSQL 12 |
| PgAdmin | 5050 |
Database UI (dev only) |
- π JWT Authentication β Register, login, access + refresh tokens
- π³ Stripe Payments β PaymentIntents with SCA compliance
- π Webhooks β Real-time payment status updates from Stripe
- β©οΈ Refunds β Full and partial refund support
- π¦ Order Management β Orders linked to payments
- π‘οΈ Security β Helmet, CORS, rate limiting, input validation, idempotency keys
- π Admin API β Revenue stats, full payment history, admin refunds
- π Swagger Docs β Interactive API docs at
/docs - π³ Docker β Full stack with one command
- β Tests β Unit and integration test suite with Jest
# 1. Clone the repo
git clone https://github.com/shanewas/payflow.git
cd payflow
# 2. Set up environment
cp .env.example .env
# Edit .env and fill in your Stripe keys and JWT secrets
# 3. Start everything
docker-compose up --build -d
# 4. Run migrations
docker-compose exec api node scripts/migrate.jsAPI available at http://localhost:8080
Client available at http://localhost:3001
PgAdmin available at http://localhost:5050
Backend:
npm install
cp .env.example .env
# Edit .env with your values
npm run migrate
npm startFrontend:
cd client
npm install
# Create client/.env with REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_...
npm startCopy .env.example to .env and fill in the values:
| Variable | Description | Example |
|---|---|---|
PORT |
API server port | 8080 |
NODE_ENV |
Environment | development |
DATABASE_URL |
PostgreSQL connection string | postgres://user:pass@localhost:5432/payflow |
STRIPE_SECRET_KEY |
Stripe secret key | sk_test_... |
STRIPE_WEBHOOK_SECRET |
Stripe webhook signing secret | whsec_... |
JWT_ACCESS_TOKEN_SECRET |
JWT access token secret | random-secret |
JWT_ACCESS_TOKEN_EXPIRATION |
Access token expiry | 15m |
JWT_REFRESH_TOKEN_SECRET |
JWT refresh token secret | random-secret-2 |
JWT_REFRESH_TOKEN_EXPIRATION |
Refresh token expiry | 7d |
CORS_ORIGIN |
Allowed CORS origin | http://localhost:3001 |
REACT_APP_STRIPE_PUBLISHABLE_KEY |
Stripe publishable key (frontend) | pk_test_... |
Get your Stripe keys at dashboard.stripe.com/apikeys
Full interactive docs available at GET /docs when the server is running.
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/auth/register |
Register a new user | β |
POST |
/auth/login |
Login and get tokens | β |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/payments/intent |
Create a payment intent | β |
GET |
/payments |
Get payment history | β |
GET |
/payments/:id |
Get payment details | β |
POST |
/payments/:id/refund |
Refund a payment | β |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/orders |
Create an order | β |
POST |
/checkout |
Start checkout for an order | β |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/webhooks/stripe |
Stripe webhook receiver | Signature |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/admin/payments |
All payments with filters | β Admin |
GET |
/admin/stats |
Revenue and status stats | β Admin |
POST |
/admin/refund/:id |
Refund any payment | β Admin |
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run only unit tests
npm run test:unit
# Run only integration tests
npm run test:integrationIntegration tests require a running PostgreSQL instance. Set
DATABASE_URLto a test database before running.
Use these in the payment form with any future expiry and any 3-digit CVC:
| Scenario | Card Number |
|---|---|
| β Payment succeeds | 4242 4242 4242 4242 |
| β Payment declined | 4000 0000 0000 0002 |
| π Requires 3D Secure | 4000 0025 0000 3155 |
4000 0000 0000 9995 |
- Set
NODE_ENV=productionin your environment - Use a process manager like PM2 for the Node.js app
- Configure your Stripe webhook in the Stripe Dashboard to point to
https://yourdomain.com/webhooks/stripe - Ensure your PostgreSQL database is secured, backed up, and accessible only from the API server
- Set all secrets to strong random values β never commit
.envto git
MIT