Skip to content
OkadaDrop

Developers

Paying for deliveries

Every delivery is prepaid by Mobile Money: we debit an account you have registered, at the moment you book. Riders never handle money, so there is nothing to collect at the door, nothing invoiced and nothing settled later.


There is one way to pay

OkadaDrop is prepaid. A delivery is charged to a Mobile Money account you registered, through Paystack, as it is booked — the recipient is never asked for anything and the rider never carries a shilling. There is no cash on delivery, no invoicing and no account terms.

This makes billing a prerequisite rather than a preference: until an account is registered, every booking you make is refused. Register one before you write the booking call, not after it starts failing.

Register the account we debit

A booking has to name an account to take the money from. Register one first — from the dashboard or with a POST — and every booking after that debits it without naming anything. There is no hosted checkout on the Partner API: there is no one on your side of the request to complete it.

  1. Register a MoMo account on your partner account. The first one you add becomes the default.

  2. Book with `payment_method: "paystack"` and no `payment_method_id`. The default is debited.

  3. Or name a specific account with `payment_method_id` when you keep more than one — a separate account per storefront, say.

Registering an account

curl -X POST https://api.okadadrop.com/api/v1/partner/payment-methods \
  -H "Authorization: Bearer $SOMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "mtn",
    "phone": "+233241112222",
    "account_name": "Acme Shop Ltd"
  }'
201 response
{
  "id": "3d9a71b4-...",
  "provider": "mtn",
  "phone": "+233241112222",
  "account_name": "Acme Shop Ltd",
  "is_default": true,
  "created_at": "2026-08-01T09:12:44Z"
}

Fields

Fields accepted when registering a Mobile Money account
providerTypemtn | vodafone | airteltigoNotesThe network the number belongs to. Registration fails if the number is not on it.
phoneTypestringNotesThe MoMo number to debit, in Ghana format.
account_nameTypestringNotesThe name on the account. Replaced by the name the network holds when it has one, since that is the copy a debit is checked against.
is_defaultTypebooleanNotesDebit this one when a booking names none. The first account you register becomes the default regardless.

Accounts are checked before they are saved

Registering an account resolves it with the network first. A number that does not exist, or belongs to a different network than the one you named, is refused with a 400 right there — rather than being accepted and failing at your first booking, when a rider is already on the way to a pickup. If the account resolves under a different holder's name, that name is what gets stored: it is the copy the debit is checked against, and a mismatch is the usual reason one is declined.

400 response
{
  "error": {
    "code": "bad_request",
    "message": "That number is not a MTN Mobile Money account. Check the number and the network it belongs to.",
    "details": {}
  }
}

You can hold more than one — a separate account per storefront, or per cost centre. GET /partner/payment-methods lists them with the default first, and DELETE /partner/payment-methods/{id} removes one. The phone number is stored as you send it; there is no edit route, so correcting a number means deleting the account and registering it again.

Booking against it

Once an account is registered, a Mobile Money booking is an ordinary booking with one field changed. The debit runs server-side as the delivery is created.

Booking body
{
  "pickup_address": "Osu, Accra",
  "pickup_lat": 5.5560, "pickup_lng": -0.1820,
  "dropoff_address": "East Legon, Accra",
  "dropoff_lat": 5.6360, "dropoff_lng": -0.1530,
  "package_size": "small",
  "recipient_name": "Ama",
  "recipient_phone": "+233209876543",

  "payment_method": "paystack"
  // No payment_method_id — your default account is debited.
  // Name one with "payment_method_id" if you keep several.
}

Book before registering an account and you get a 400 that says exactly what is missing:

400 response
{
  "error": {
    "code": "bad_request",
    "message": "No Mobile Money account is registered on this partner account. Add one with POST /partner/payment-methods, name one with payment_method_id, or book with payment_method 'cash'.",
    "details": {}
  }
}

Payment status

Every delivery carries a payment_status alongside its delivery status. The two move independently — that is the part worth internalising.

Payment statuses and what each one means
pendingMeaningThe debit has been requested and Paystack has not confirmed it yet. Normal for a few seconds after booking.
paidMeaningThe money is in — usually within seconds of booking.
failedMeaningThe debit was declined: an empty wallet, a wrong number, a network outage. The delivery is still booked and a rider may already be riding to it.

Rules worth knowing

Booking is not blocked on payment

A delivery dispatches as soon as it is booked, in parallel with the debit. That keeps riders moving, but it means a `failed` payment can belong to a delivery already on its way — and since the rider collects nothing at the door, a failed debit is money you will have to chase yourself. Watch `payment_status` on the webhook payload rather than assuming a booked delivery is a paid one.

Removing an account is not a refund

Deleting a registered account stops future bookings debiting it. Deliveries already booked against it are untouched, and money already taken stays taken.

Cancelling does not refund you

A delivery is debited when it is booked, not when a rider accepts, so by the time you cancel the money has usually already moved. Cancellation stops the delivery; it does not return the fare, and there is no refund endpoint. Mail [email protected] to have one returned.

NextAPI referenceEvery endpoint, with request and response bodies.