Skip to content

How we built Sarva Logistics

A last-mile delivery product, now in testing. Here is what was hard, what testing exposed, and how we fixed it.

The problem.

Last-mile delivery in Abuja runs on personal contacts and haggled prices. Customers can't see where their package is. Riders can't predict their work or their earnings. Sarva Logistics connects customers with verified riders, through transparent pricing, live tracking and accountability on both sides.

The idea is simple. Getting the money, the locations and the matching right is not.

Money that moves exactly once.

In a delivery product, every naira has to land in the right place, once. Four problems we found and fixed:

  • Cash deliveries paid riders twice. A rider kept the customer's cash and had the full fare credited to their wallet. Cash orders now deduct only the platform's commission.
  • Duplicate payment notices. Paystack sometimes resends its "payment succeeded" message, and two copies arriving together could both credit a rider. Every credit is now claimed inside a database transaction, so only the first one counts.
  • Paid riders never credited. A card payment only credited a rider who was already assigned when the money arrived. Payment is now two steps: capture (the money arrived, and matches the exact fare) and settle (the rider is paid once, when they enter the customer's delivery code).
  • Payouts that could go negative. Payouts now accept only positive amounts, and the database refuses any update that would take a wallet below zero.

Security, closed before launch.

Testing found gaps that a production system can't have. We tightened who can create administrator accounts, made every payment confirmation prove it really came from the payment provider, ensured development shortcuts can never run in production, and made delivery codes impossible to leak to a rider through an order record.

Failures nobody could see.

Some of the worst bugs don't announce themselves.

  • 19 of the app's 50 server calls went to addresses that didn't exist, and the screens hid the errors. Riders had no working way to mark a package as picked up or delivered, so no delivery could be completed.
  • Admin buttons failed silently, because of how empty requests were sent. One fix in the shared request code now prevents it everywhere.
  • Every typed address landed in Lagos unless it came from a short list of ten places, so Abuja orders couldn't match Abuja riders. Address search and road distances moved to a mapping service that accepts our server, with fallbacks.
  • The price shown wasn't the price charged. The booking screen used old rates while the server charged current ones. Every screen now shows one server-calculated breakdown that adds up to the total.

What real testing showed.

With real people, in production, we confirmed:

  • a complete delivery, from a rider accepting the job to the rider entering the customer's delivery code;
  • a test-mode card payment, from checkout through confirmation to the rider search;
  • that the server accepts requests only from Sarva's own website, and rejects forged payment messages.

Live testing also exposed what no local test had: admin actions that didn't work, a rider chat that never delivered messages, a price that appeared to rise, and a second order that never reached a rider whose screen was open. All are fixed. The last one led to the biggest change yet.

What's next: smarter rider matching.

The original matcher searched once and gave up. Its replacement, built and tested and now rolling out:

  • widens the search every 30 seconds (2, then 4, then 6 km);
  • drops riders whose GPS goes quiet for two minutes;
  • picks the best nearby rider, by rating, then reliability;
  • makes one offer at a time, so two riders can never accept the same order;
  • re-sends missed offers when a rider reopens the app.

Built with: Next.js, NestJS, PostgreSQL, Redis, Paystack, Vercel and Render.

Have a product like this in mind?

We bring the same care to client work: the money, the edge cases, and the failures nobody sees until real users arrive.