Open source

Ledgerline

Open-source platform, built with Claude Code · Payments platform built like a bank's

A payments platform where money is never created, lost or moved twice — a double-entry ledger on an event log, card payments and payouts as sagas, an outbox into Kafka, in-line fraud scoring, ClickHouse analytics, a gRPC merchants' API, and OpenTelemetry tracing, all proven by breaking it on purpose.

Ledgerline preview

Problem

Payment systems are judged by the day things fail: a lost answer, a dead database or a duplicate request must never create money, lose it or move it twice, and demos rarely show that.

Solution

A double-entry ledger on an event log, sagas that never guess, idempotency everywhere and an outbox into Kafka, then chaos runs, load tests, a fraud model and alerts, each measured instead of assumed.

Built in

Nothing lost or done twice over 11 chaos scenarios and 40,461 requests; fraud caught 88% vs 37% for rules; ~430 ledger transfers/s on one CPU; every alert proven to fire; a live demo and CI.

Overview

Ledgerline is an open-source payments platform I built with Claude Code to show what a bank's core needs: money that is never created, lost or moved twice, even when everything around it fails. A double-entry ledger in Kotlin and Spring Boot keeps an append-only event log in PostgreSQL; balances are projections rebuilt from it, every write is idempotent, and an audit recomputes the books. Card payments, refunds and payouts run as state machines and sagas on top of it, and every change reaches Kafka through a transactional outbox.

It is proven by breaking it while a client keeps paying: services, PostgreSQL and Kafka killed, networks cut, answers cut off mid-way. Over 11 chaos scenarios and 40,461 requests (4,188 of them sent twice at once), a checker found nothing lost and nothing done twice. Load tests found the hot spots: the ledger does about 430 transfers a second on one CPU, shedding the excess instead of falling over.

A LightGBM model on real-time features from Kafka caught 88% of fraud at 0.7% false declines against 37% for tuned rules, measured against a simulator's hidden truth; ClickHouse analytics agree with the ledger to the kopeck. Merchants get a gRPC API, signed webhooks and a TypeScript SDK: with the service killed mid-payment, all 1,085 changes still reached the example shop. Traces follow a payment through the outbox, the worker and webhooks, and every alert was proven to fire by injecting the fault it watches.

What it does

  • A double-entry ledger in Kotlin and Spring Boot on an append-only event log in PostgreSQL, with idempotent writes, no overdraft under any concurrency, and an audit that recomputes the books
  • Card payments, refunds and payouts to a misbehaving simulated bank as state machines and sagas; every change reaches Kafka through a transactional outbox
  • Fraud scored in line by a LightGBM model on features kept from Kafka, measured against a simulator's hidden truth; analytics in ClickHouse that agree with the ledger to the kopeck
  • A gRPC API, signed webhooks and a TypeScript SDK for merchants; traces that follow a payment through the outbox, the worker and webhooks; SLO alerts proven to fire by injecting each fault

What's next

Hiring for a full-stack or Python role — or need something like this built? Let's talk.

I'm open to offers — on-site or hybrid in Moscow, or remote; full-time or contract. I reply within 48 hours — faster on Telegram.

Get in touch TelegramDownload CV

Alhassan Alfarran.

© 2026 · Designed and built by me with Next.js, Tailwind and Framer Motion.

My local time: · Moscow

Notes
How this site is built

Stack

Next.js (App Router) and React, styled with Tailwind CSS and animated with Framer Motion. The contact form sends email through Resend; the site is hosted on Vercel.

Three languages, one layout

English, Russian and Arabic each have their own address (/en, /ru, /ar) and share one set of components. The layout uses logical CSS properties (start/end instead of left/right), so Arabic mirrors right to left without separate styles. The server sends every page with its language and text direction already set, so nothing flips after loading, and the Arabic font is only downloaded when Arabic text is on screen.

Performance and accessibility

Sections below the first screen skip rendering until you scroll near them, and the quick menu loads on first use. Everything works from the keyboard, with a skip link and visible focus, and animations switch off when your system asks for reduced motion.

Source code on GitHub