A .NET 10 Aspire microservices-based payment platform implementing Event Sourcing, Transactional Outbox, Idempotency, CQRS, and Saga patterns for reliable distributed transaction management. Includes a Blazor Server customer web frontend and a YARP-based API Gateway.
⚠️ Production Readiness: This is a demonstration project. See Production Readiness Summary for requirements to deploy to production.
- Identity Service: User authentication service with OAuth2/JWT (RS256) and refresh token rotation
- Account Service: Account management, credit/debit operations
- Card Service: Debit/credit card issuance and management
- Payment Service: Payment API with full transaction lifecycle and Saga-based distributed transactions
- Merchant Service: Merchant registration, management, and admin approval workflow
- Partner Service: Partner (bank/card provider) registration, API key management, and payment dispatch
- API Gateway: YARP-based reverse proxy with rate limiting, health checks, and load balancing
- Customer Web App: Blazor Server frontend for customer-facing operations
- Event Sourcing: All state changes captured as immutable events
- Transactional Outbox: Ensures reliable event publishing with at-least-once delivery
- Idempotency: Duplicate request prevention for critical operations
- CQRS (Command Query Responsibility Segregation): Separate read and write models
- Saga Pattern: Distributed transaction management with compensation logic
- .NET 10: Latest .NET framework
- Aspire: Microservices orchestration and service discovery
- Blazor Server: Interactive web frontend
- YARP: API Gateway reverse proxy
- PostgreSQL: Primary database for persistent storage
- Kafka: Event streaming and message broker (KRaft mode)
┌─────────────────────────────────────────────────────────────────┐
│ Aspire AppHost │
│ (Orchestration Layer) │
└─────────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
│ │
┌─────────▼──────────┐ ┌────────▼────────┐
│ Customer Web App │ │ API Gateway │
│ (Blazor Server) │─────────►│ (YARP) │
└────────────────────┘ └───────┬─────────┘
│
┌─────────┬────────────┬─────────────┼──────────────┬──────────┐
│ │ │ │ │ │
┌──────▼──┐ ┌───▼────┐ ┌─────▼───┐ ┌──────▼─────┐ ┌─────▼───┐ ┌────▼────┐
│Identity │ │Account │ │ Card │ │ Payment │ │Merchant │ │ Partner │
│Service │ │Service │ │ Service │ │ Service │ │ Service │ │ Service │
└─────────┘ └────────┘ └─────────┘ └──────┬─────┘ └─────────┘ └─────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌────▼─────┐ ┌────▼────┐ ┌────▼────┐
│PostgreSQL│ │ Kafka │ │ Outbox │
│ (DB) │ │ (Events)│ │Processor│
└──────────┘ └─────────┘ └─────────┘
PaymentHub/
├── PaymentHub.AppHost/ # Aspire orchestration
├── PaymentHub.ServiceDefaults/ # Shared service configurations
├── src/
│ ├── Services/
│ │ ├── PaymentHub.Services.Identity/ # Identity & Auth service (OAuth2/JWT)
│ │ ├── PaymentHub.Services.Account/ # Account management
│ │ ├── PaymentHub.Services.Card/ # Card management
│ │ ├── PaymentHub.Services.Payment/ # Payment processing & transactions
│ │ ├── PaymentHub.Services.Merchant/ # Merchant management
│ │ └── PaymentHub.Services.Partner/ # Partner (bank/card provider) integration
│ ├── Gateway/
│ │ └── PaymentHub.Gateway/ # YARP API Gateway
│ ├── Web/
│ │ └── PaymentHub.Web.Customer/ # Blazor Server customer web app
│ ├── Infrastructure/
│ │ ├── PaymentHub.Infrastructure.EventSourcing/ # Event Store
│ │ ├── PaymentHub.Infrastructure.Outbox/ # Outbox Pattern
│ │ └── PaymentHub.Infrastructure.Saga/ # Saga Pattern
│ └── Shared/
│ └── PaymentHub.Shared.Domain/ # Domain events & models
└── docker-compose.yml # Infrastructure services
- .NET 10 SDK
- Docker & Docker Compose
- Visual Studio 2022 or VS Code with C# extension
- Start Infrastructure Services:
docker-compose up -dThis starts:
- PostgreSQL (port 5432)
- Kafka (port 9092) - KRaft mode, no ZooKeeper required
- Kafka UI (http://localhost:8080)
- PgAdmin (http://localhost:5050)
- Run the Application:
dotnet run --project PaymentHub.AppHostThis starts all microservices with Aspire orchestration. Access the Aspire dashboard to monitor services. The Customer Web App is available via the customer-web endpoint shown on the dashboard.
- Alternative - Run Individual Services:
# Identity Service
dotnet run --project src/Services/PaymentHub.Services.Identity
# Account Service
dotnet run --project src/Services/PaymentHub.Services.Account
# Card Service
dotnet run --project src/Services/PaymentHub.Services.Card
# Payment Service
dotnet run --project src/Services/PaymentHub.Services.Paymentdotnet build PaymentHub.slndotnet test PaymentHub.slnAuthentication Endpoints:
POST /api/identity/register- Register new userPOST /api/identity/login- User loginPOST /api/identity/logout- User logoutGET /api/identity/users/{userId}- Get user details
POST /api/accounts- Create new accountPOST /api/accounts/{accountId}/credit- Credit accountPOST /api/accounts/{accountId}/debit- Debit accountGET /api/accounts/{accountId}- Get account details
POST /api/cards- Issue new cardPOST /api/cards/{cardId}/activate- Activate cardPOST /api/cards/{cardId}/block- Block cardGET /api/cards/{cardId}- Get card details
POST /api/payments- Initiate paymentPOST /api/payments/{paymentId}/authorize- Authorize paymentPOST /api/payments/{paymentId}/capture- Capture paymentPOST /api/payments/{paymentId}/refund- Refund paymentGET /api/payments/{paymentId}- Get payment status
POST /api/transactions- Initiate transaction to merchantPOST /api/transactions/{transactionId}/payments- Add payment to transactionPOST /api/transactions/{transactionId}/complete- Complete transactionPOST /api/transactions/{transactionId}/cancel- Cancel transactionGET /api/transactions/{transactionId}- Get transaction details
POST /api/merchants- Register new merchantGET /api/merchants/{merchantId}- Get merchant detailsGET /api/merchants/owner/{ownerId}- Get merchants by ownerGET /api/merchants/status/{status}- Get merchants by statusGET /api/merchants- Get all merchants (admin)PUT /api/merchants/{merchantId}- Update merchant informationPOST /api/merchants/{merchantId}/approve- Approve merchant (admin)POST /api/merchants/{merchantId}/reject- Reject merchant (admin)POST /api/merchants/{merchantId}/suspend- Suspend merchant (admin)POST /api/merchants/{merchantId}/reactivate- Reactivate merchant (admin)
POST /api/v1/partners/register- Register new partner (bank/card provider)POST /api/v1/partners/{partnerId}/configure- Configure partner webhook/callback URLsGET /api/v1/partners/{partnerId}- Get partner detailsPOST /api/v1/partners/{partnerId}/suspend- Suspend partner
POST /api/v1/partners/{partnerId}/payments- Send payment to partner for processingGET /api/v1/partner-payments/{requestId}- Get partner payment request status
Every state change is stored as an immutable event. Aggregates are reconstructed by replaying events:
var events = await eventStore.GetEventsAsync(aggregateId);
var aggregate = new Account();
aggregate.LoadFromHistory(events);Events are stored in an outbox table and published asynchronously to Kafka, ensuring reliable delivery:
// OutboxProcessor runs as a background service
// Polls outbox for unprocessed messages
// Publishes to Kafka and marks as processedDuplicate requests are detected and rejected:
var idempotencyKey = $"register-{email}";
if (await idempotency.IsProcessedAsync(idempotencyKey))
{
return Results.Conflict();
}Commands (writes) and Queries (reads) are separated:
- Commands modify aggregates via Event Store
- Queries read from optimized read models
- Read models updated via event handlers
Distributed transactions use compensating transactions on failure:
// Payment Saga coordinates:
// 1. Debit Account
// 2. Authorize Payment
// 3. Capture Payment
// On failure: Compensate in reverse orderUpdate in appsettings.json or via Aspire service discovery:
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Database=paymenthub;Username=postgres;Password=postgres"
}
}{
"Kafka": {
"BootstrapServers": "localhost:9092"
}
}- Aspire Dashboard: Service health, metrics, traces
- Kafka UI: Message monitoring at http://localhost:8080
- PgAdmin: Database management at http://localhost:5050
- OAuth2/JWT Authentication: Production-grade OAuth2 with JWT tokens (RS256)
- Refresh Token Rotation: Automatic rotation with 7-day expiration
- OpenID Connect Discovery: Standard OIDC endpoints for authentication
- Password Hashing: Argon2id (active)
- SQL Injection Prevention: Parameterized queries throughout
- Input Validation: Basic validation on all endpoints
- Event Sourcing: Immutable audit trail for all state changes
- API Gateway: YARP-based gateway with rate limiting and health checks
- PCI DSS Compliance: Full card numbers are accepted in-flight but only masked card numbers (last 4 digits) are persisted and CVV is never stored — tokenization (Stripe, Adyen) recommended to fully remove PCI scope
- Encryption at Rest: No database encryption for sensitive data
- TLS Enforcement: HTTPS available but not enforced in all environments
- MFA: Multi-factor authentication not implemented
- Secrets Management: Keys in configuration files (need Azure Key Vault or AWS Secrets Manager)
- Comprehensive Audit Logging: GDPR logging exists, need full security event logging
See Production Readiness Status for detailed roadmap and PCI DSS Compliance Review for payment card security requirements.
📊 Production Readiness Status - NEW Current implementation status (35% complete)
📋 Production Readiness Summary - Executive overview of production requirements
📘 Production Readiness Review - Original comprehensive 44KB assessment covering:
- Security assessment and recommendations
- Scalability and performance requirements
- Monitoring and observability setup
- Operational readiness (CI/CD, DR, backups)
- Compliance requirements (PCI DSS, GDPR)
- Testing strategy
- Timeline and cost estimation
🔒 PCI DSS Compliance Review - NEW Comprehensive payment card security assessment
Critical Finding: Full card numbers are accepted at runtime but only masked card numbers (last 4 digits) are ever persisted and CVV is never stored — PCI scope is reduced but tokenization (Stripe, Adyen) is recommended to eliminate it entirely.
Recommendation: Implement tokenization (Stripe, Adyen) to remove PCI scope
- Timeline: 2-4 weeks
- Cost: $20K-$40K
- Alternative: Full PCI compliance (6-12 months, $200K-$500K)
PCI DSS Status:
⚖️ GDPR Executive Summary - Management overview of GDPR requirements and risks
📗 GDPR Implementation Guide - Complete 58KB technical guide covering:
- GDPR fundamentals and legal requirements
- Personal data inventory across all services
- Implementation of all 7 data subject rights
- Technical architecture and API specifications
- Database schemas and code examples
- Testing strategies and compliance checklists
- 8-week implementation timeline (€52K-€104K)
📋 GDPR Implementation Status - Current progress tracker (40% complete)
🚀 GDPR Quick Start - Week-by-week implementation checklist with SQL scripts
💻 GDPR Code Examples - Complete C# reference implementations
GDPR Status:
Current Status:
- Event Sourcing, CQRS, Saga, Outbox patterns
- PostgreSQL persistence for event store and read models
- Kafka integration with webhook consumer
- Comprehensive unit tests (148 tests)
- API Gateway (YARP) with rate limiting, health checks, load balancing
- Distributed tracing (OpenTelemetry)
- Circuit breakers (Polly via ServiceDefaults)
- API versioning
- Health checks
- OAuth2/JWT authentication (RS256, refresh tokens, OIDC discovery)
- GDPR infrastructure (40% complete - Phase 1 done)
- Argon2id password hashing (active)
- Partner Service (partner registration, API key management, payment dispatch)
- Customer Web App (Blazor Server frontend)
- PCI DSS partial compliance (masked card storage, CVV never persisted)
- PCI DSS tokenization - Integrate Stripe/Adyen to fully remove PCI scope
- Complete GDPR (6 weeks) - Phases 2-4 remaining
- Encryption at rest (database encryption)
- TLS enforcement (HTTPS only)
- Secrets management (Azure Key Vault or AWS Secrets Manager)
- MFA implementation (2-3 weeks)
- Production monitoring and alerting
- CI/CD pipeline
- Kubernetes deployment
- Database backups and disaster recovery
- Comprehensive audit logging (beyond GDPR)
- Performance testing and optimization
See Production Readiness Status for detailed roadmap and timelines.
This is a demonstration project showcasing microservices architecture patterns with industry-standard design patterns. It demonstrates production-quality architecture but requires significant security, operations, and compliance work before production use.
For production deployment, see the Production Readiness Review for comprehensive requirements.
MIT License