Engineering

Backend systems, APIs and web applications for products that need more than a template.

I design and build production-oriented systems with clear boundaries, reliable data flows and practical operational visibility.

Backend · APIs · Payments · Queues · Integrations · Observability

payments/charge.go

Core capabilities

What I build

Six areas where I take technical ownership from design through to production.

01

APIs and backend services

REST APIs, service boundaries, domain logic, validation, authentication and integrations.

02

Payments and authentication

Payment flows, webhooks, user identity, permissions and failure handling.

03

Queues and background jobs

Reliable asynchronous processing, retries, dead-letter workflows and workers.

04

Internal tools

Systems for operations, support, reporting, administration and workflow control.

05

Web applications

Product interfaces connected to real backend logic, not only static frontend screens.

06

Integrations

External providers, messaging platforms, CRMs, billing systems and internal services.

Selected architecture problems

The questions that decide whether a system survives production

These are the problems I have actually had to answer, and how I answer them. They are also the reason I write my own tools.

Problem 01

A payment that must never happen twice

The payment provider stops answering in the middle of a charge. Did the customer pay or not? Retry blindly and you may charge them twice; give up and you may lose the payment. I build the system so every payment attempt carries a unique key: if the same request comes in again, it gets the first result back instead of creating a second charge. Balances are calculated from the full history of transactions, so a retry can never double them.

Problem 02

Notifications that arrive twice, late or out of order

Payment providers and other services confirm events with automatic notifications (webhooks). In practice those arrive twice, in the wrong order or hours late, and the sender considers that normal. So the system never trusts a notification on arrival: it checks who sent it, saves it, filters out duplicates and only then acts on it. Its own outgoing notifications retry a limited number of times and then land in a review queue instead of hammering the receiver forever.

Problem 03

Which part of the system is allowed to decide what

When responsibilities are not clearly divided, every change starts breaking something in an unrelated place, and eventually nothing can be updated safely. My rule is simple. The entry point of the system only checks and routes requests. Every business decision lives in the one part that owns the relevant data. If two parts fight over the same data, the split is wrong, and I fix the split.

Problem 04

Making sure important events are never lost

An update can be pushed to the receiver instantly, but if the receiver happens to be down at that moment, it is gone. So I save every event first and deliver it second. The saved record is the source of truth: delivery can be retried, and anything that was missed can be sent again later. This is exactly how AlertLoop works.

Problem 05

Understanding what went wrong at 3am

When something fails in the middle of the night, a log line that just says "error" helps nobody. I record every step of a request under one shared id, so the whole story can be read from start to finish instead of being pieced together from fragments. And when an external service goes down, it switches off one feature, not the whole product.

The pattern

Every one of these is about the moment something fails

The happy path is the easy part. What separates a demo from a product is what happens on the second attempt, the duplicate delivery and the provider that stops answering.

Technical focus

The stack I use most

I'm not tied to one stack. These are the tools I reach for by default, because I know how they behave under load and how they fail. But the system's boundaries matter more than the language it's written in.

PHP Node.js TypeScript Go SQL PostgreSQL MySQL / MariaDB Docker REST APIs Queues Background workers Webhooks Telegram WhatsApp Payments Auth Observability

Observability

I built the tools I wanted to have

Most production incidents are not hard because the bug is subtle. They are hard because nobody can see what happened. Logs are scattered, the delivery that failed left no trace, and the only evidence is a customer saying it didn't work.

I got tired of rebuilding the same two pieces on every project, so I published them. Traceloom connects related events into one readable timeline grouped by trace. AlertLoop makes sure the events that matter actually reach a human, with retries, dead letters and replay when they don't.

Both are open source and both are running code, not slideware. They are the clearest evidence I can offer of how I build.

event: payment.settled
store event (trace_id)
route to channels
deliver · email / telegram / webhook
retry with backoff on failure
dead letter after the cap
→ replay, once the cause is fixed

The AlertLoop delivery path, in short.

Need an engineer who can understand both the system and the product behind it?

Describe the system, the constraint and what is currently breaking. I'll tell you what I would do first and whether I'm the right person to do it.