A company's money2025

Partner-bank payment integration

The API layer partner banks talk to, so a payment can be confirmed by the bank instead of matched up by hand afterwards.

Role
Sole engineer
Stack
Node.js · Firebase Cloud Functions · Firestore

Client work. System names, screenshots and business figures are omitted.

What it took
  • One engineer, building against an external financial institution's requirements
  • Four separate internal systems that all had to agree on the same payment
  • A workflow already in daily use that could not get worse for anyone in it
The problem

Customers pay by bank transfer, mobile money or in person. Every one of those payments had to be evidenced by hand: a form filled in with the service, the customer, the currency, the amount, the date and which account received it, plus an uploaded image as proof.

Someone then checked each of those, one at a time, against the real account records. That checking step was the bottleneck, and it grew with the business.

What I did

The API layer partner banks call: look up available services, confirm a booking exists from its reference, and report back that a payment has been received.

Authentication and authorisation on every endpoint, treated as a design constraint from the first line rather than a layer added at the end.

The documentation the bank's own engineering team built against, and ongoing technical support to them through the integration.

Decisions

The parts worth arguing about.

01

Every payment gets a generated identifier

Issued once, at the point the payment is created. The same payment cannot be recorded twice, no matter how many times a message is delivered or retried.

02

The validation endpoint returns as little as possible

Confirming a booking requires checking a reference against a customer name, so the endpoint returns the minimum needed to perform that check and nothing else. It is exposed to another organisation; it should know as little about our customers as the job allows.

03

Unverified input never touches primary data

A confirmed payment lands in a staging collection first. Only once it is approved does it move into the main collections and cascade to everything downstream.

04

A person approves, every time

Payments stay pending until someone from the accounts team checks them. This is the decision I'd defend hardest. Automating that last step would have been easy and would have removed the only place a mistake gets caught before it becomes a real one.

What came out

A partner bank tested the integration thoroughly, was satisfied, and issued a live key on the strength of that testing. An external financial institution reviewed the work and approved it for production.

Wider rollout across the remaining partners is still in progress, for reasons that aren't technical.