Ahmed YassinCase study 01 / 04

← All work

Rebuilding settlement around how the business actually paid people

Company
DropX
Role
Co-founder & Product Lead
Dates
Jan 2025 – Present
Domain
Marketplace finance & operations

“The system settled weekly. The business never once did.”

settlement state flow · schematic

not eligible — the defaulteligible — delivered + cash collectedprocessing — merchant requests payoutsettled — figures frozenon hold · deferred · return pending

Context

DropX is a B2B dropshipping marketplace: suppliers on one side, merchants selling on their own channels on the other. Every order to date has settled as cash on delivery: the end customer pays the courier, and DropX reconciles against courier settlement cycles. A second path — holding an order in payment verification until a merchant settles directly and uploads proof — is built and has not yet been needed. It is a counterparty-risk control put in before the risk arrived, which is the only sensible order to build one in.

Either way, DropX ends up holding money that belongs to a merchant, and has to give it back.

That handover is settlement. It is the part of a marketplace that people trust or don’t.

The challenge

I built settlement as a weekly batch — a settlement run, settlement lines, a payout cycle. It is how marketplaces are supposed to work, and it is what I had seen everywhere else. It shipped in November 2025.

DropX never ran a single weekly cycle.

What actually happened was that a merchant would message and ask for their money, and we would work out what they were owed and transfer it — offline, outside the system. The weekly tables kept filling up with numbers nobody used and nobody trusted.

By the time I looked at it properly, three things were true:

  • No order knew whether it had been paid. Settlement state was either derived weekly on the fly or held as a manual override in a side collection. Nothing on the order row said “this one is done.”
  • The per-order money math was invisible. Two real costs came out of merchant proceeds with nothing in the UI showing them: the shipping DropX was charged by the courier, and DropX’s own cut of the item price.
  • The weekly numbers were wrong, so ops didn’t use them, which meant nobody noticed they were wrong.

Underneath all of that was a live money leak, and it surfaced from both ends at once. Reconciling what the couriers had charged DropX against what DropX had recouped left a gap that kept reappearing; separately, a merchant disputed what they were owed. Both pointed at the same rule.

DropX recovers its shipping cost by deducting it from what the merchant is owed. The old rule only did that when the merchant had charged their customer less than our rate — the subsidy case. Charge exactly our rate, and it deducted nothing: DropX paid the courier and recouped zero.

Which sounds like a boundary condition, and wasn’t. The checkout defaults a merchant’s shipping charge to the plan rate, so “exactly our rate” is not an edge of the distribution — it is a spike in the middle of it. The condition that looked like an off-by-one was sitting on thousands of ordinary orders, and I have since counted them.

What I did

Modelled settlement as its own axis

Settlement status is not a stage of fulfilment. An order can be delivered and unpaid at the same time, and conflating the two is what made the old model unusable. So settlementStatus became a separate axis with its own transitions — not eligible, eligible, processing, settled, on hold, deferred, return pending — the same way order confirmation already had its own.

The default is deliberately not eligible: an order is not payable until it is delivered and the cash is actually collected. In a COD-first market that gap is the whole risk, and defaulting to payable would have inverted it.

Decoupled the payout from the cost data

The design decision I’d defend hardest is a boring-looking one. The merchant’s payout is computed only from prices the merchant can see — what they charged, what DropX charges them, what shipping they collected, and DropX’s rate. It does not depend on what the courier actually charged DropX, or what the supplier actually charged.

Those two costs matter enormously — they are DropX’s entire margin — but they live in the margin report, not the payout path. The reason is operational: carrier and supplier cost data is incomplete and always will be. If settlement depended on it, every gap in a supplier price sheet would become a merchant waiting on their money. Incomplete data now degrades a report instead of blocking a payment.

Made one shipping rule instead of a special case

DropX always deducts its rate-plan base rate for shipping, whatever the merchant charged the customer. The merchant keeps whatever shipping they collected. One rule, two lines of arithmetic, no subsidy branch — and the leak closes as a consequence of the rule rather than as a patch on top of it.

Froze the numbers at the moment of payment

A settled order snapshots the figures it was settled on. Prices move; a payout that silently recomputes six weeks later is not auditable, and “we paid you the right amount, trust the current numbers” is not an answer a merchant should have to accept.

Wrote down what I was not building

Returns and RTO settlement, partial payouts, merchant-facing visibility, automatic eligibility, and retiring the weekly model — all explicitly deferred, in the design doc, with the data model left open for each. Manual-first on eligibility was the one I went back and forth on: automating it would have been a day’s work, and it would have automated a judgement call that ops was still learning how to make.

Outcome

Where it actually stands, stated precisely, because settlement is exactly the place a vague “shipped” should not be trusted: schema, engine, admin endpoints, tests and the money-breakdown UI merged to master at the end of July 2026, behind a feature flag with a single-operator allowlist. Zero production settlements have run through it. The weekly model is dormant rather than deleted, and its legacy write path is closed.

So the leak is fixed in code and still open in production. I could describe this as shipped and be technically right, and a merchant would still be paid by the old arithmetic tomorrow.

The rule that replaces it is shorter than the logic it replaced, and that is the part I’d point at: not more code around the special case, but removing the special case. One deduction, applied whatever the merchant charged. I have also now counted the exposure — the orders and the total that should have been recouped — which is a number I can walk an interviewer through and would rather not put on a public page.

What changes when it rolls out is smaller than the engine and matters more: every order carries its own settlement state and its own money breakdown, so a payout becomes something ops reads instead of reconstructs.

What I’d do differently

Weekly was never a decision. It was the default shape of a settlement system — what marketplaces do — and I built it without once checking it against how DropX actually moved money. There was no evidence behind it, and I never went looking for any.

The information was there the whole time. Every payout was a merchant messaging to ask for their money, and not one of them was weekly. Eight months after I built it — six of them with live payouts running — I finally read that as a product signal instead of as ops noise, and in the meantime the gap between the model and the reality was quietly costing us on the shipping line.

What I take from it: before modelling a process, watch how it is being done by hand today. The manual workaround is not a stopgap to be replaced — it is the requirement, already validated by the people doing it. I now start there, and I keep the old model switched off rather than deleted until the new one has survived contact with real money.