Payments core. Byte4Bit, 2023 to now. Senior backend engineer. Node.js, TypeScript, AWS.
88Pay
A payments core I led from zero through a full microservices migration: payments, accounts, identity, files, analytics, notifications and public APIs.
The problem
A payments core is not one service that got big. It is seven different failure conversations wearing one deployment, and the first migration decision is where the seams go.
I led the core from zero: payments, accounts, identity, files, analytics, notifications and the public APIs, as Node.js and TypeScript services moving real money with strict validation, rate limiting, secure coding and observability.
Seven domains with their own boundaries
Each context owns its data and its failure mode, so an incident in notifications is not an incident in payments.
Validation before the money moves
In a payment system a bug is an accounting problem, so strict validation and rate limiting are part of the first version rather than a hardening pass.
Public APIs as a deliberate surface
The external contract is designed rather than leaked, which is what keeps internal refactors from becoming customer-facing breakage.
Decisions and the price I paid for them
Split by domain, not by layer
Boundaries follow the seven business contexts, so a change to how accounts work touches one service instead of one horizontal layer across all of them.
Trade-off accepted
Seven deployables cost more operational attention than one, and some workflows now cross a network boundary that used to be a function call.
Treat every write as an accounting event
Strict validation, rate limiting and secure-coding review sit in front of anything that moves money, because the cost of a wrong write is not a retry.
Trade-off accepted
More rejected requests at the edge, and more work to get a legitimate but unusual transaction through.
Observability as a first-class requirement
A money system has to answer "what happened to this transaction" as a query, not as an investigation.
Trade-off accepted
Instrumentation is written alongside the feature and maintained forever, whether or not anyone reads it.
