davidgracemann
FlossPay
Java

The Linux Kernel Of Payments Infrastructures ; Enterprise Payments Aggregator for immutable reliability and forensic auditability. Rooted in Linux principles Of Community . No vendor lock-inโ€”governance, code, and ledger all verifiable. Implements: idempotency, distributed retries, circuit-breaker

Last updated Jul 9, 2026
36
Stars
7
Forks
23
Issues
+1
Stars/day
Attention Score
69
Language breakdown
No language data available.
โ–ธ Files click to expand
README

FlossPay

Free/Libre Open-Source Payments Infrastructure

License: MIT Java Version Spring Boot PostgreSQL Redis


Table of Contents


Overview

FlossPay is an enterprise-grade payment processing infrastructure implementing UPI (Unified Payments Interface) rails with support for extensible payment methods. Built on Spring Boot 3.x and Java 21 LTS, it provides:

  • Asynchronous Transaction Processing: Redis Streams for reliable queue-based processing
  • Idempotency Guarantees: RFC 4122 UUIDv4 with HMAC-SHA256 replay resistance
  • Audit-First Architecture: Immutable transaction ledger with SHA-256 checksums
  • Horizontal Scalability: Stateless API and worker services deployable on Kubernetes
Current Release: v0.2-alpha (UPI rail hardened)

Target Compliance: PCI-DSS v4.0, SOC 2 Type II, ISO 27001


System Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                              CLIENT LAYER                                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                          โ”‚
โ”‚  โ”‚   Merchant   โ”‚  โ”‚   Mobile     โ”‚  โ”‚   Web        โ”‚                          โ”‚
โ”‚  โ”‚   App        โ”‚  โ”‚   SDK        โ”‚  โ”‚   Portal     โ”‚                          โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                โ”‚                โ”‚
          โ–ผ                โ–ผ                โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           FLOSSPAY CORE                                      โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚        API SERVICE                  โ”‚    โ”‚      WORKER SERVICE         โ”‚   โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚   โ”‚
โ”‚  โ”‚  โ”‚ REST API   โ”‚  โ”‚ Idempotency  โ”‚  โ”‚    โ”‚  โ”‚ Stream Consumer     โ”‚   โ”‚   โ”‚
โ”‚  โ”‚  โ”‚ Controller โ”‚  โ”‚ Service      โ”‚  โ”‚    โ”‚  โ”‚ (XREADGROUP)        โ”‚   โ”‚   โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚   โ”‚
โ”‚  โ”‚        โ”‚                           โ”‚    โ”‚             โ”‚              โ”‚   โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚   โ”‚
โ”‚  โ”‚  โ”‚   TransactionApiProducer  โ”‚     โ”‚    โ”‚  โ”‚  UPI/NPCI Gateway   โ”‚   โ”‚   โ”‚
โ”‚  โ”‚  โ”‚   (Business Logic Layer)  โ”‚     โ”‚    โ”‚  โ”‚  Client (Mock)      โ”‚   โ”‚   โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚           โ”‚                                              โ”‚                   โ”‚
โ”‚           โ”‚         Redis Streams                        โ”‚                   โ”‚
โ”‚           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ transactions.main โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”‚                    transactions.dlq (DLQ)                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚
          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         DATA LAYER                                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”‚
โ”‚  โ”‚  PostgreSQL 15+                                                          โ”‚โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ transactions (BIGSERIAL PK)                                          โ”‚โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ transaction_history (Audit trail)                                    โ”‚โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ idempotency_keys (Request deduplication)                             โ”‚โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ webhook_callbacks (Outbound notifications)                           โ”‚โ”‚
โ”‚  โ”‚  โ”œโ”€โ”€ servicecircuitbreakers (Health monitoring)                         โ”‚โ”‚
โ”‚  โ”‚  โ””โ”€โ”€ clientratelimits (Quota management)                                โ”‚โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Component Responsibilities

| Component | Technology | Responsibility | |-----------|------------|----------------| | API Service | Spring Boot 3.2, Java 21 | Public REST API, request validation, idempotency enforcement, HMAC authentication, transaction enqueueing | | Worker Service | Spring Boot 3.2, Java 21 | Async stream consumption, retry logic with exponential backoff, DLQ management, UPI gateway integration | | Shared Libraries | Java Module System | DTOs, JPA entities, repositories, validation annotations, exception hierarchy | | Database Layer | PostgreSQL 15+, Flyway | Relational ledger with audit tables, migration management | | Message Queue | Redis 7+ Streams | Reliable async processing, consumer groups, dead letter queue |


Repository Structure

FlossPay/
โ”œโ”€โ”€ api-service/                 # REST API and public interface
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ main/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ java/com/openpay/api/
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ controller/         # REST controllers (Transaction, Health)
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ service/            # Business logic (TransactionApiProducer, Idempotency)
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ security/           # HMAC authentication
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ config/             # Spring configuration (Redis, Web, Logging)
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ filter/             # Rate limiting filter
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ resources/
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ application.properties
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ db/migration/       # Flyway migrations
โ”‚   โ”‚   โ””โ”€โ”€ test/                     # Unit and integration tests
โ”‚   โ””โ”€โ”€ pom.xml
โ”œโ”€โ”€ worker-service/              # Background processing
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ main/java/com/openpay/worker/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ processor/              # Stream consumer and retry logic
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ client/                 # NPCI/UPI gateway client
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ config/                 # Redis worker configuration
โ”‚   โ”‚   โ””โ”€โ”€ resources/
โ”‚   โ””โ”€โ”€ pom.xml
โ”œโ”€โ”€ shared-libs/                 # Common domain model
โ”‚   โ”œโ”€โ”€ src/main/java/com/openpay/shared/
โ”‚   โ”‚   โ”œโ”€โ”€ dto/                      # Data Transfer Objects
โ”‚   โ”‚   โ”œโ”€โ”€ model/                    # JPA Entities
โ”‚   โ”‚   โ”œโ”€โ”€ repository/               # Spring Data Repositories
โ”‚   โ”‚   โ”œโ”€โ”€ exception/                # Exception hierarchy
โ”‚   โ”‚   โ””โ”€โ”€ validation/               # Custom validators
โ”‚   โ””โ”€โ”€ pom.xml
โ”œโ”€โ”€ database/                    # Database utilities (reserved)
โ”œโ”€โ”€ scripts/                     # Development and deployment scripts
โ”‚   โ”œโ”€โ”€ gen_hmac.py             # HMAC signature generator
โ”‚   โ””โ”€โ”€ scaffold.sh             # Project scaffolding
โ”œโ”€โ”€ .github/
โ”‚   โ”œโ”€โ”€ workflows/              # GitHub Actions CI/CD
โ”‚   โ””โ”€โ”€ ISSUE_TEMPLATE/         # Issue templates
โ”œโ”€โ”€ pom.xml                     # Parent Maven POM
โ”œโ”€โ”€ justfile                    # Task runner commands
โ”œโ”€โ”€ CODEOFCONDUCT.md
โ”œโ”€โ”€ CONTRIBUTING.md
โ”œโ”€โ”€ SECURITY.md
โ””โ”€โ”€ LICENSE

Prerequisites

Required

  • Java: OpenJDK 21 LTS (tested with Temurin)
  • Maven: 3.9.x or later
  • PostgreSQL: 15.x or later
  • Redis: 7.x or later (with Streams support)

Optional

  • Docker: 24.x or later (for containerized deployment)
  • Docker Compose: 2.x or later (for local development stack)
  • Just: Task runner (alternative to Make)

Building from Source

1. Clone Repository

git clone https://github.com/davidgracemann/FlossPay.git
cd FlossPay

2. Provision Infrastructure

# PostgreSQL
psql -U postgres -c "CREATE DATABASE flosspay_db;"
psql -U postgres -c "CREATE USER flosspayuser WITH PASSWORD 'securerandom_password';"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE flosspaydb TO flosspayuser;"

Redis

redis-cli ping

Expected: PONG

3. Build

# Full build with tests
./mvnw clean verify

Skip tests (development only)

./mvnw clean install -DskipTests

4. Run Services

# Terminal 1: API Service
java -jar api-service/target/api-service-1.0-SNAPSHOT.jar

Terminal 2: Worker Service

java -jar worker-service/target/worker-service-1.0-SNAPSHOT.jar

Or using Just task runner:

just runa    # Run API service
just runw    # Run Worker service

Configuration

API Service (api-service/src/main/resources/application.properties)

# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/flosspay_db
spring.datasource.username=flosspay_user
spring.datasource.password=${DB_PASSWORD}
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

Flyway

spring.flyway.enabled=true spring.flyway.locations=classpath:db/migration

Redis

spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=${REDIS_PASSWORD} spring.redis.timeout=2000ms spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-idle=8

Server

server.port=8080 server.servlet.context-path=/api/v1

Logging

logging.level.root=INFO logging.level.com.openpay=DEBUG logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

Worker Service (create: worker-service/src/main/resources/application.properties)

# Database (same as API)
spring.datasource.url=jdbc:postgresql://localhost:5432/flosspay_db
spring.datasource.username=flosspay_user
spring.datasource.password=${DB_PASSWORD}

Redis

spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=${REDIS_PASSWORD}

Server

server.port=8081

Environment Variables

| Variable | Required | Description | Example | |----------|----------|-------------|---------| | DBPASSWORD | Yes | PostgreSQL password | securerandom_password | | REDISPASSWORD | Yes | Redis password | redissecure_pass | | HMACSECRET | Yes | HMAC signing key (min 32 bytes) | base64encoded_key |


API Specification

Base URL

http://localhost:8080/api/v1

Authentication

All payment endpoints require HMAC-SHA256 authentication:

  • Concatenate request body JSON + idempotency key
  • Compute HMAC-SHA256 using shared secret
  • Base64 encode result
  • Include in X-HMAC header

Endpoints

1. Initiate Payment

POST /pay
Content-Type: application/json
Idempotency-Key: <uuid-v4>
X-HMAC: <base64-hmac-signature>

Request: { "senderUpi": "sender@upi", "receiverUpi": "receiver@upi", "amount": 100.00 }

Response (200 OK): { "id": 12345, "status": "QUEUED", "message": "Transaction queued" }

Response (400 Bad Request): { "error": "Sender and receiver UPI must be different" }

Response (409 Conflict): { "error": "Duplicate request" }

2. Initiate Collect (Pull)

POST /collect
Content-Type: application/json
Idempotency-Key: <uuid-v4>
X-HMAC: <base64-hmac-signature>

Request: { "senderUpi": "payer@upi", "receiverUpi": "payee@upi", "amount": 250.50 }

Response (202 Accepted): { "id": 12346, "status": "REQUESTED", "message": "Collect request queued" }

3. Get Transaction Status

GET /transaction/{id}/status

Response (200 OK): { "id": 12345, "status": "COMPLETED", "senderUpi": "sender@upi", "receiverUpi": "receiver@upi", "amount": 100.00, "createdAt": "2024-01-15T10:30:00Z", "updatedAt": "2024-01-15T10:30:05Z" }

Response (404 Not Found): { "error": "Transaction not found" }

4. Health Check

GET /health

Response (200 OK): { "status": "UP", "timestamp": "2024-01-15T10:30:00Z", "version": "0.2-alpha" }

GET /health/ready

Response (200 OK): { "status": "READY", "checks": { "database": "UP", "redis": "UP" } }

Response (503 Service Unavailable): { "status": "NOT_READY", "checks": { "database": "DOWN", "redis": "UP" } }

cURL Examples

# Generate HMAC signature
python3 scripts/gen_hmac.py

Make payment request

curl -X POST http://localhost:8080/api/v1/pay \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -H "X-HMAC: YOURHMACSIGNATURE" \ -d '{ "senderUpi": "test@upi", "receiverUpi": "merchant@upi", "amount": 100.00 }'

Check status

curl http://localhost:8080/api/v1/transaction/12345/status

Database Schema

transactions

| Column | Type | Constraints | Description | |--------|------|-------------|-------------| | id | BIGSERIAL | PRIMARY KEY | Auto-generated transaction ID | | sender_upi | VARCHAR(100) | NOT NULL | Payer UPI ID | | receiver_upi | VARCHAR(100) | NOT NULL | Payee UPI ID | | amount | NUMERIC(15,2) | NOT NULL | Transaction amount | | status | VARCHAR(20) | NOT NULL | queued, processing, completed, failed | | created_at | TIMESTAMPTZ | DEFAULT NOW() | Creation timestamp | | updated_at | TIMESTAMPTZ | NULL | Last update timestamp |

Indexes:

CREATE INDEX idxtxstatuscreated ON transactions(status, createdat);

transaction_history

| Column | Type | Constraints | Description | |--------|------|-------------|-------------| | history_id | BIGSERIAL | PRIMARY KEY | Audit record ID | | transaction_id | BIGINT | FOREIGN KEY | References transactions.id | | prev_status | VARCHAR(20) | NOT NULL | Previous status | | new_status | VARCHAR(20) | NOT NULL | New status | | changed_at | TIMESTAMPTZ | DEFAULT NOW() | Change timestamp |

idempotency_keys

| Column | Type | Constraints | Description | |--------|------|-------------|-------------| | idempotency_key | VARCHAR(64) | PRIMARY KEY | Client-provided UUID | | transaction_id | BIGINT | FOREIGN KEY | Associated transaction | | created_at | TIMESTAMPTZ | DEFAULT NOW() | Key creation time |

webhook_callbacks

| Column | Type | Constraints | Description | |--------|------|-------------|-------------| | callback_id | BIGSERIAL | PRIMARY KEY | Callback record ID | | transaction_id | BIGINT | FOREIGN KEY | References transactions.id | | url | VARCHAR(255) | NOT NULL | Webhook endpoint URL | | status | VARCHAR(20) | NOT NULL | pending, sent, failed | | lastattemptedat | TIMESTAMPTZ | NULL | Last attempt timestamp | | attempts | INTEGER | DEFAULT 0 | Delivery attempts |

servicecircuitbreakers

| Column | Type | Constraints | Description | |--------|------|-------------|-------------| | service_name | VARCHAR(50) | PRIMARY KEY | External service identifier | | state | VARCHAR(20) | NOT NULL | CLOSED, OPEN, HALF_OPEN | | failure_count | INTEGER | DEFAULT 0 | Recent failure count | | lastfailureat | TIMESTAMPTZ | NULL | Last failure timestamp |

clientratelimits

| Column | Type | Constraints | Description | |--------|------|-------------|-------------| | client_id | VARCHAR(64) | PRIMARY KEY | API client identifier | | tokens | INTEGER | DEFAULT 100 | Available quota tokens | | last_refill | TIMESTAMPTZ | DEFAULT NOW() | Last quota refill |


Testing

Unit Tests

./mvnw test

Integration Tests

./mvnw verify -Pintegration-tests

Test Coverage Requirements

  • Line coverage: โ‰ฅ 85%
  • Branch coverage: โ‰ฅ 80%
  • Mutation coverage (PIT): โ‰ฅ 75%

Performance Tests

# Using k6
k6 run scripts/load-test.js

Using Gatling

gatling.sh -sf src/gatling/scala

Security

Vulnerability Reporting

DO NOT open public issues for security vulnerabilities.

Email: security@flosspay.dev

Include:

  • Detailed vulnerability description
  • Affected versions/branches
  • Steps to reproduce or PoC
  • Impact assessment
24-hour acknowledgment SLA

Security Controls

| Control | Implementation | Standard | |---------|---------------|----------| | Authentication | HMAC-SHA256 request signing | RFC 2104 | | Idempotency | UUIDv4 keys with TTL | RFC 4122 | | Transport | TLS 1.3 mandatory | RFC 8446 | | Encryption | AES-256-GCM at rest | FIPS 197 | | Audit Trail | SHA-256 signed logs | FIPS 180-4 | | Retry Logic | Exponential backoff with jitter | FIPS 140-2 |

Compliance Mapping

  • PCI-DSS v4.0: Req 3.4 (PAN protection), Req 10 (logging), Req 11 (testing)
  • SOC 2 Type II: CC6.1 (logical access), CC7.2 (system monitoring)
  • ISO 27001: A.12.4 (logging), A.14.2.1 (secure development)

Contributing

Development Workflow

  • Fork the repository
  • Create feature branch: git checkout -b feature/description
  • Implement changes with tests
  • Run pre-commit checks: ./scripts/pre-commit.sh
  • Commit with signed-off-by: git commit -s
  • Push and open Pull Request

Commit Message Format

subsystem: Brief description (50 chars)

Detailed explanation of what changed and why. Can span multiple lines.

Signed-off-by: Developer Name <email@example.com>

Code Review Criteria

  • [ ] All tests pass
  • [ ] Code coverage maintained
  • [ ] Security scan clean
  • [ ] JavaDoc updated
  • [ ] No breaking changes (or documented)
  • [ ] Reviewed by 2+ maintainers

Branch Strategy

  • main: Production-ready code
  • feature/*: New features
  • fix/*: Bug fixes
  • hotfix/*: Critical production fixes
See CONTRIBUTING.md for complete guidelines.

Performance Characteristics

| Metric | Target | Notes | |--------|--------|-------| | API Latency (p99) | < 100ms | Without external gateway call | | Worker Throughput | 100+ TPS | Per instance | | Database Connections | 20 | HikariCP pool size | | Redis Timeout | 2s | Connection timeout | | Retry Backoff | 2^n seconds | Exponential, max 5 attempts |


Troubleshooting

Issue: "Failed to connect to Redis"

Solution:

# Verify Redis is running redis-cli ping

Check configuration in application.properties

spring.redis.host=localhost spring.redis.port=6379

Issue: "Database connection refused"

Solution:

# Verify PostgreSQL is running pg_isready -h localhost -p 5432

Check database exists

psql -U postgres -c "\l" | grep flosspay

Verify credentials

psql -U flosspayuser -d flosspaydb -c "SELECT 1"

Issue: "HMAC validation failed"

Solution:

  • Verify HMAC secret matches between client and server
  • Check message format: JSON body + idempotencyKey
  • Use provided script: python3 scripts/gen_hmac.py

License

MIT License - See LICENSE

Copyright (c) 2024 David Grace

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Contact

  • Security Issues: security@flosspay.dev
  • General Questions: GitHub Discussions
  • Bug Reports: GitHub Issues (use templates)

Maintainers:

  • David Grace (@davidgracemann) - Project Owner & Chief Architect
  • Goutham Rajesh (@gouthamdev) - Product Manager

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท davidgracemann/FlossPay ยท Updated daily from GitHub