Most financial APIs are powerful but incomplete. The gaps they leave are real engineering problems that every developer building on top of them has to solve from scratch. I've been solving them, and making the solutions open source.

Most of my work lives at the intersection of payment infrastructure, tax compliance, and the developer tooling that fintech runs on. I've built TaxID and LinkdFund, and shipped production software across Kenya's financial stack.

When something important is undocumented, broken by design, or left entirely to the developer to figure out, I tend to build the fix and publish it.

Mar 2026

Daraja handles STK Push initiation. It doesn't handle what happens when the user locks their phone mid-payment, switches apps, or closes yours entirely before the callback arrives. This Flutter package manages the full payment lifecycle: direct Safaricom API calls without a proxy server, WebSocket delivery of payment status via Appwrite Realtime, automatic state recovery when the app returns from background, and killed-app recovery on next launch via SharedPreferences. Accepts any Kenyan number format — 0712345678, +254712345678, or raw 9-digit — with automatic normalization.

Flutter Dart M-Pesa Appwrite Real-time
2025 — Present

KRA's eTIMS API has no official Python SDK. Every developer integrating it rebuilds the same things: OAuth token refresh, VAT arithmetic across five tax bands, idempotency for in-flight network failures — the Schrödinger's Invoice problem where a timeout mid-POST leaves the invoice state unknown. This SDK handles all of that, plus async support with full API parity and a supplier onboarding gateway for informal sector compliance under Finance Act 2023 §16(1)(c). The tax calculator works offline with no credentials.

Python KRA eTIMS Async Idempotency
2026 — Present

An npm package. Daraja gives you STK Push initiation. It doesn't handle what happens when the callback never arrives, when Safaricom sends the same callback three times under load, when a client retries and gets double-charged, or when your database says SUCCESS and Safaricom has no record of it. This TypeScript library handles all of that: idempotent initiation, atomic callback deduplication, polling fallback, and a reconciliation pass for payments that fall through every other safety net. v0.2.0 adds a webhook relay server — point your Safaricom CallbackURL at the relay and it guarantees delivery to your app with exponential-backoff retries, even if your server restarts mid-payment window.

TypeScript Node.js PostgreSQL M-Pesa Webhooks
Feb 2026

Safaricom's Daraja documentation doesn't document its own error codes comprehensively. Developers hit cryptic failures and have nowhere to look. A searchable reference for every error the Daraja API returns — causes, fixes, and context the official docs don't provide. Includes an llms.txt so AI tools can read it correctly. Community-contributed: open a PR to add an error code you've hit.

JavaScript HTML Open Source
Mar 2026 — Present

Full-stack short-stay rental platform built for a Nairobi property host — real bookings, Paystack payments (M-Pesa + card), a yield engine that auto-prices vacancy gaps, AI-powered guest chat with WhatsApp integration, and an OTA sync pipeline for Airbnb, Booking.com, and VRBO. Admin dashboard with revenue tracking and guest CRM. PWA with offline support and push notifications. Built on Next.js + FastAPI, deployed on Vercel and Railway. Live and in use.

Next.js FastAPI PostgreSQL Paystack TypeScript PWA
dev.to
What Daraja 3.0 actually changed for developers — and what it did not
Safaricom's biggest API update since 2019 — what actually changed at the platform level, what stayed the same, and why the core integration challenges are identical to Daraja 2.0.
LinkedIn
KRA eTIMS will reject your invoices because of how Python stores numbers
Why your invoice gets rejected by KRA's validator — a dive into float arithmetic errors, residual drift, and why Decimal is the only safe boundary.
LinkedIn
What eTIMS Integration Actually Requires
VSCU, state isolation, and why most implementations stop at the wrong layer. The infrastructure problem most developers don't hit until it's too late.
dev.to
Safaricom's sandbox STK Query API returns FAILED for successful payments. Here's what's happening.
Why the Daraja STK Query endpoint reports FAILED even when the callback confirms success — and how to build reconciliation logic that handles it.
dev.to
I measured M-Pesa STK Push polling lag on a real device. The variance will ruin your UX.
Same code, same device, same network — 3 seconds one run, 39 the next. A teardown of why fixed polling schedules fail.

Building TaxID — compliance infrastructure for Kenya's informal economy. Thinking about what it means to build software for systems that were never designed to be programmed against.

Most of the interesting engineering problems in East Africa aren't algorithmic. They're about trust, reliability, and what happens when the network drops.

Based in Nairobi, Kenya (GMT +3). ronnyabuto@gmail.com.