Skip to content

shanewas/payflow

Repository files navigation

PayFlow — Data Pipeline Architecture

This document describes the data pipeline powering PayFlow's payment processing system. See README.md for the main project overview.

Overview

PayFlow processes payments through a pipeline that handles: user registration → order creation → payment intent → Stripe API → webhook processing → database updates → admin reporting.

User Action → Express API → PostgreSQL → Stripe API → Webhook → DB Update → Admin UI

Data Flow

1. User registration → payment setup

POST /auth/register
→ Create user record (PostgreSQL: users table)
→ Generate JWT access + refresh tokens
→ Return tokens to client

2. Order creation → payment intent

POST /payments/intent
→ Validate JWT
→ Create order record (PostgreSQL: orders table, status="pending")
→ Create Stripe PaymentIntent via Stripe API
→ Store Stripe customer_id + payment_intent_id in orders table
→ Return client_secret to frontend

3. Stripe webhook → payment confirmation

Stripe sends POST /webhooks/stripe
→ Verify Stripe signature (stripe-signature header)
→ Route by event type:
  - payment_intent.succeeded → update order status="completed", trigger fulfillment
  - payment_intent.payment_failed → update order status="failed", notify user
  - charge.refunded → update order status="refunded"
→ Acknowledge webhook to Stripe (return 200)

4. Refund flow

POST /payments/:id/refund
→ Admin authentication (adminAuth middleware)
→ Call Stripe refunds API
→ Update order status="refunded" in PostgreSQL
→ Return refund confirmation

Database schema

Core tables

users

id | email | password_hash | is_admin | created_at | updated_at

orders

id | user_id | stripe_payment_intent_id | stripe_customer_id
amount | currency | status | created_at

payments

id | order_id | stripe_charge_id | amount | status
refunded_at | created_at

Indexes

  • orders(user_id) — for user order history queries
  • orders(stripe_payment_intent_id) — for webhook lookup
  • payments(order_id) — for payment history per order

Webhook reliability

Stripe webhooks are retried by Stripe if your endpoint returns non-200. PayFlow:

  • Immediately returns 200 on webhook receipt (does not wait for DB commit)
  • Uses database transactions for payment state updates
  • Handles duplicate webhook events idempotently (check stripe_payment_intent_id before update)

Graceful shutdown handler (server.js) ensures in-flight webhook processing completes before shutdown.

Environment variables

DATABASE_URL=postgresql://user:pass@host:5432/payflow
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
JWT_SECRET=your_jwt_secret
JWT_EXPIRE=7d
NODE_ENV=development
PORT=8080

Key design decisions

Decision Why
Separate /webhooks route Stripe requires raw body for signature verification — cannot use Express body parsers before this route
Idempotent webhook handler Stripe retries failed webhooks; order status updated only if current status is "pending"
Return 200 immediately Stripe's retry window is short; slow DB operations shouldn't cause duplicate processing
JWT with access + refresh Refresh token allows session extension without re-login; access token short-lived for security
Decimal amounts in cents Stripe uses integers (cents) to avoid floating-point errors

Docker setup

# docker-compose.yml (key services)
api:   # Node.js on :8080
db:    # PostgreSQL on :5432
admin: # pgAdmin on :5050 (dev only)
docker-compose up -d
# API available at localhost:8080
# pgAdmin at localhost:5050

Testing

npm run test          # Unit tests
npm run test:e2e     # End-to-end (requires Stripe test keys)

What this shows for backend/data roles

  • End-to-end payment pipeline design (Stripe is an industry-standard integration)
  • Webhook-based event processing (real-time data ingestion pattern)
  • Idempotent processing for external API callbacks
  • PostgreSQL transactions with proper rollback on failure
  • Docker-based local development environment
  • JWT authentication with refresh token rotation

See README.md for quick start. See src/ for the actual implementation.

About

A full-stack payment integration system built with Node.js, Express, Stripe API, PostgreSQL and React. Features JWT auth, webhooks, refunds, and Docker support.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors