All projects

Payment Ledger

A personal ASP.NET Core API for double-entry balances: JWT auth, Postgres, idempotent transfers, HMAC-signed webhooks, and an outbox worker that posts deposits after accept.

Role
Personal project
Year
2026
Links
GitHub
Stack
  • C#
  • ASP.NET Core
  • EF Core
  • PostgreSQL
  • JWT
  • Serilog
  • OpenTelemetry
  • Docker

Context

I wanted a clean place to practice money-correctness patterns outside client work: journal entries that must balance, idempotent transfer keys, optimistic concurrency on account balances, and reliable webhook intake without doing the side effect in the request path.

What I built

Clean architecture across Domain, Application, Infrastructure, and Api projects on ASP.NET Core 10 and EF Core with Postgres. Transfers run in one transaction with Postgres xmin optimistic concurrency; inbound webhooks verify HMAC, return 202, and an outbox worker claims rows with FOR UPDATE SKIP LOCKED, backs off, then dead-letters. Serilog logging plus optional OpenTelemetry metrics.

Details

  • Double-entry journal: money stored as integer minor units; every entry's lines must sum to zero
  • Idempotent transfers via Idempotency-Key: same key and body replays the response; same key and different body returns 422
  • HMAC-signed webhook intake with an outbox worker for deposits into a seeded system clearing account
  • Health checks, Serilog, and OpenTelemetry meters for transfers, webhooks, and outbox lag
  • Integration tests with Testcontainers when Docker is available

Status

Open source at github.com/mgiwa78/payment-ledger.