COD fraud is an economics problem, not a fraud problem
6 min readNexusHand Engineering
Cash on delivery is not a rounding error
In Bangladeshi e-commerce, cash on delivery is not an alternative payment method sitting alongside cards and mobile wallets. For most online shoppers buying from an unfamiliar seller, it is the default, and often the only method they will use. bKash and Nagad have made mobile money routine for peer transfers, bill payments, and increasingly for paying trusted, established shops, but paying a stranger's Facebook page in advance is a different kind of trust, and most buyers are not willing to extend it yet. They pay once the parcel is actually in their hands. A commerce platform built for this market has to treat COD as the primary path, not an edge case bolted onto a card-first checkout designed somewhere else. qCommerz supports bKash, Nagad, SSLCommerz, and COD side by side for exactly this reason, and across the merchants running on it, cash on delivery is typically the heaviest of the four by order volume.
The failure mode is simple, and it is expensive
The mechanism is straightforward. A merchant ships an order. The courier attempts delivery. The customer refuses it, does not answer the phone, or has already bought the same item from a different shop that week. The parcel returns. The merchant has already paid the courier's dispatch fee, often pays a return fee too, has packaging cost sunk, and has stock sitting in transit instead of on a shelf.
The cost compounds in ways that are easy to underestimate from outside. A refused delivery is not just one wasted trip. Stock earmarked for that order is unavailable to sell to someone else while it sits in transit and on the way back, the courier fee is paid whether or not the parcel is accepted, and a merchant in a remote delivery zone pays a higher dispatch fee for the same failed outcome as one in the city. None of this shows up as a single line item labelled 'fraud cost.' It shows up as a margin that is thinner than the order book suggests it should be.
At the margins typical of small resale businesses, a handful of refused deliveries in a week can erase the profit from every order that did complete. Some of this is not malice. A customer orders the same item from three shops, planning to keep whichever arrives first and ignore the rest, or simply changes their mind between placing the order and hearing the doorbell. The label 'fraud' suggests an intent that is often absent. The economic damage to the merchant is identical either way, which is why we think about this as an economics problem before we think about it as a trust problem.
Why verifying every order is the wrong fix
The obvious response is to call or SMS-verify every COD order before it ships. It does reduce refused deliveries. It also adds a delay and a friction point to every single order, including the large majority placed by genuine customers who were always going to receive and pay for exactly what they ordered. A merchant running their own shop rarely has staff whose whole job is making hundreds of confirmation calls a day, so blanket verification either happens inconsistently or slows the business down enough to cost more in abandoned orders than it saves in refused ones. It treats a probability problem as if it were a yes-or-no gate, and punishes the ordinary customer to catch an occasional bad one.
Scoring risk instead of interrogating everyone
The approach we built into qCommerz treats this as a scoring problem, not a screening problem. New orders are checked against delivery history available through the courier relationship: has this phone number or address produced refused or unreachable deliveries before. That produces a risk signal, not a hard block. Low-risk orders go straight to dispatch, the way most honest COD orders should. Only the orders that score as risky get routed into a manual step, a confirmation call or SMS, before a courier fee is spent on them.
The signal itself is ordinary: how has this phone number, or this delivery address, behaved on past orders, rather than anything guessed from the order content itself. A pattern of refusals and unreachable attempts is a stronger predictor than the size of the order or what was bought, in the same way a customer's own repayment history predicts a loan default better than the loan amount does. Building the check around delivery history rather than order content also means it is harder to fool, because most orders that turn out badly look entirely ordinary on paper.
The point of scoring rather than blocking is that friction gets spent where it has a chance of paying for itself. Verifying a first-time customer with no history and an ordinary-looking order is a cost with no expected return. Verifying an address that has refused three deliveries in the past month is a cost that usually prevents exactly the loss it is meant to prevent.
The goal is not to catch every fake order. It is to spend verification effort only where it is likely to pay for itself.
The other half: orders that never finish
Fraud gets the attention, but the mirror-image problem costs merchants just as much and is easier to fix. A customer starts checkout, enters a phone number, maybe a delivery address, and never confirms. Some of that is genuine disinterest. A meaningful share of it is a customer who was interrupted, lost signal, took a phone call, or paused to think about delivery timing and never came back to finish. Capturing that abandoned state instead of discarding it lets a merchant follow up on the same channel the customer already used to try to buy. This is not a fraud control. It is recovered revenue that a blanket-verification mindset tends to ignore, because it is focused entirely on stopping bad orders rather than rescuing almost-good ones. Reasoned through simply: far more customers abandon a good-faith order mid-checkout than ever place a bad-faith one, so the revenue available to recover this way is often the larger opportunity of the two, even though fraud gets the headlines.
What a merchant can do without any software
Not every fix requires a platform, and it is worth saying plainly which parts do not. A merchant can keep a simple log, even a spreadsheet, of phone numbers that have refused delivery before, and check new orders against it by hand at low volume. Charging a small non-refundable advance specifically for delivery zones with a history of problems is a reasonable, low-tech filter. Calling only the orders that look unusual, a delivery address well outside the usual area, an order size that does not match browsing behaviour, gets most of the benefit of verification at a fraction of the cost of calling everyone. A merchant can also simply ask their courier partner what delivery-attempt history they are willing to share; many will expose enough for a shop owner to check manually, no integration required, before ever paying for software to do it automatically.
Where this still falls short
A risk score is a probability, not a guarantee, and it is worth being honest about where it breaks down. A first-time customer with no order history anywhere gives the model nothing to work with. The cold-start problem is real, and a genuinely new bad actor with a clean-looking number will get through at least once before a pattern exists to catch them. The quality of the underlying signal also depends on how good the courier's own delivery-outcome data is, and that varies between partners and can lag reality by days. There is also a fairness question worth sitting with: a score built on delivery history can end up flagging an honest, repeat customer who happens to live in an area with a poor delivery record for reasons that have nothing to do with them. Treating a flag as a reason to verify, never as a reason to refuse an order outright, is how we try to keep that risk contained, though it does not remove it entirely. None of this makes COD fraud disappear as an economic fact of this market. It changes the odds in the merchant's favour, which is a more honest claim than promising it goes away.