ASO Ltd.

Blog

What a delivery address needs in Douala

In six screenshots of a ride hailing app in Douala, most suggestions were landmarks rather than streets. Here is how that changed the way we store a delivery destination.

· 6 min read

We took six screenshots of a ride hailing app while using it in Douala, and looked at what it offered as destinations.

Most of what came back were landmarks. A roundabout at Maetur. A polyclinic. A fruit market. A secondary school. A petrol station. The street-style entries that did appear looked like Rue 1.805 and Rue 1.195.

That is one app on one evening, not a survey of the city. But it was enough to make us look again at our own checkout, because we are building a food delivery service for Douala and our address field assumed something different.

The shape of the usual address field

A typical checkout asks for street, number, city, postcode. That shape carries assumptions: that streets are named, that buildings are numbered, and that the people living in them use those numbers.

Where those assumptions do not hold, the form still accepts input. That is the part worth noticing. The customer types something, the order goes through, and if the text is not enough to find the door, nobody discovers it until a courier is standing in the road making a phone call.

So the design question is not how to collect an address. It is what to collect that gets somebody to a door.

Three fields, not one

We now treat a destination as three separate things, because they answer different questions.

The landmark. Where in the city: "Rond-Point Maetur, Bonamoussadi". The piece a customer can always produce, and what they would say to a taxi driver.

The point. Coordinates, when we can get them. Useful because a navigation app can consume them, and optional because someone who declines the location permission still has to be able to order.

The entrance. How to find the door once you are on the right street: "Portail bleu en face de la pharmacie", blue gate opposite the pharmacy.

The third is the one we had not built, and the one we now think matters most for delivery. A ride ends at a kerb, where the driver phones you and you walk out. A delivery ends at a door, and every call a courier makes comes out of a thin margin.

The bug we shipped ourselves

Worth being concrete about, because the assumption survives even when you think you have accounted for it.

Our checkout read the phone's current position and attached it to the order as the delivery point. Beside it sat a text box where the customer typed the address they wanted. Both travelled with the order.

Order lunch from your office for delivery at home and that order carried two destinations: the pin said office, the text said home. Our courier app navigates from the pin. The food would have gone to the office.

It never showed up in testing, because when you test you are usually sitting at the address you are ordering to. Code review found it, not a customer, which is the only reason this reads as a lesson rather than an apology.

The fix was not a better address field. The customer now chooses a destination on one screen, where the landmark, the entrance note and the point are entered together. To be precise about what that does and does not do: it removes the automatic assignment of device location as the destination. It cannot verify that a typed landmark and a chosen point refer to the same place. Someone can still pick the wrong pin deliberately. What changed is that the app no longer decides for them, and the button that reads the GPS says "I am at this address now" rather than "use my location", because the second phrasing invites a tap from somebody who is somewhere else.

What we would suggest storing

  1. Keep the landmark free-form, and do not impose an address format. Requiring a street number rejects "carrefour du lycée, behind the pharmacy", which is a perfectly good answer. That is different from no validation at all: we still require some text, cap the length, and escape it on the way out. The rule is no foreign address shape, not no checks.
  2. Treat coordinates as optional and never infer them. A missing point is a normal state. Inferring one from the device is exactly how we ended up with two destinations on one order.
  3. Store the entrance note as its own field. Merged into the address, you cannot show it to the right person at the right time.
  4. Give the entrance note to the courier only. The restaurant has no reason to know which gate is the customer's. Make that an explicit decision in the query rather than a side effect of what the API happens to return.
  5. Consider bounding delivery distance by the vendor. We have vendors in Douala and in Yaounde, so a single service area would mean deciding where a city ends. Distance from the restaurant is a simpler starting rule, and a courier does ride from the restaurant. Two measured examples from our own data, using the same delivery point: 199.2 km from one vendor, refused; 5.7 km from another, accepted. Those are straight-line distances. They say nothing about whether a road exists or how long the ride takes, and a vendor radius is a first rule rather than a replacement for service areas later.

Note the interaction with point two: if either the customer or the vendor has no coordinates, there is nothing to measure, and our check lets the order through rather than blocking it. A distance rule only applies where both points exist.

A small spot check on open map data

The obvious next feature is a suggestion list: type three letters, pick a landmark. Before building it we checked what open map data returns for Douala.

In six Nominatim searches restricted to Cameroon, we found three of the intended places, got no result for two queries, and got a wrong-city result for one: a search for a central Douala market returned a market in Nkongsamba, roughly 104 km away.

That is a spot check, not a census. A query returning nothing does not prove the place is absent from the map, since phrasing, naming and filters all change what comes back. What it does show is that results need bounding to the area you serve: a wrong answer in another city is worse than none, because an empty result gets retyped and a plausible one gets accepted.

If you do build autocomplete, note that a viewbox on its own is only a preference; it takes bounded=1 to make it a restriction, per the Nominatim search documentation. Note also that the public endpoint's usage policy lists auto-complete search under unacceptable use, so it is not the right backend for that feature.

We have not built it. It is a provider decision that deserves its own evidence, including what each provider's terms allow you to store.

The honest limit

None of this is launched. The app is in testing, payments are running against a sandbox, and the landmark suggestions above do not exist yet.

What we can say is narrower: if you are building something in Cameroon that has to reach a physical person, the address field is not a solved problem to copy from a template. Treat the landmark, the point and the entrance as three separate fields, let two of them be missing, and put the entrance note in front of the person doing the delivering.

The last fifty metres is where the cost sits.