Appearance
AgriTrade Exchange as a Mamlaka merchant
AgriTrade Exchange takes and sends Kenyan shilling payments through the Mamlaka payment gateway, and issues prepaid cards to its drivers through Mamlaka's virtual card Partner API. This page is the reference for setting the exchange up as a merchant: what it uses, what it needs from Mamlaka, and how it behaves.
Being released
The money rails described here are built and tested, and are being rolled out. Until a rail is switched on for the exchange, invoices are paid by bank transfer or mobile money and recorded by Finance, as today.
What the exchange is
AgriTrade Exchange is a commodity exchange for East African crops: cassava, sorghum, millet and the products made from them. Farmers deposit crops in registered warehouses and receive warehouse receipts, recorded on the Celo blockchain. Buyers order from those receipts, the exchange moves the goods by truck and across borders, and invoices, escrow and payouts close each trade. See What the exchange is for the whole picture.
Money moves in three directions, and the gateway carries the shilling part of each:
| Who | Money | Through Mamlaka |
|---|---|---|
| Buyers | Pay order invoices and fund escrow | M-Pesa or Airtel prompt (STK push), or the hosted card page |
| Farmers and transporters | Receive early payouts, balances and freight | M-Pesa or Airtel B2C |
| Drivers | Receive money for the road: fuel, tolls, spares | A Mamlaka virtual card loaded from the exchange's float, or B2C to their phone |
Stablecoin payments (USDC and USDT) go over Stellar and Celo instead, and never through the gateway.
Products used
Payment gateway
| Product | Endpoint the exchange calls | Used for |
|---|---|---|
| Mobile money collection (STK push) | POST /mobile/initiate | A buyer pays an invoice or funds escrow from their phone |
| Card collection (hosted page) | POST /card/initiate | A buyer pays by card on Mamlaka's page; the exchange never sees card details |
| Mobile money transfer (B2C) | POST /mobile/transfer | Payouts to farmers, freight to transporters, advances to drivers |
| Transaction status | GET /transaction?reference= | The exchange's only source of truth for an outcome |
Every request carries:
externalId: the exchange's own key for that payment, written down before the request is sent and reused on every retry. A second request with the same key is the same payment.callbackUrl:https://apiexchange.yeshara.network/api/v1/hooks/mamlaka/payments.displayNameon the phone prompt: AgriTrade Exchange.
Amounts for mobile money are whole shillings; the exchange refuses to send a mobile-money amount with cents. B2C transfers are KES 10 or more.
Virtual cards (Partner API)
| Action | Used for |
|---|---|
| Cardholder KYC (with ID front, back and selfie) | A driver applies for a card |
| Quote, then issue | A card is issued once the driver passes KYC |
| Quote, then deposit | A card is loaded for a trip |
| Freeze and unfreeze | Finance stops or restarts a card |
| Card balance, float balance | Shown on Fleet → Driver cards |
| Webhooks (signed) | KYC decisions and card changes |
The exchange does not call the card-details endpoint: card numbers and CVVs are never shown in, or stored by, the exchange. See Driver virtual cards.
What the exchange needs from Mamlaka
For each environment, sandbox first, then live:
- A merchant account for AgriTrade Exchange, with its merchant id and API password.
- Gateway access enabled for that merchant on mobile money collection, B2C and card collection.
- A card profile for the merchant. The exchange is built and tested for KES card payments; say whether USD card payments are enabled too.
- The M-Pesa paybill the merchant collects into, and the float it pays B2C out of.
- A callback signing secret for the merchant, so every gateway callback carries an
X-Mamlaka-Signaturethe exchange can check. - For cards: the Partner API key and webhook signing secret, and a funded KES float.
Send the credentials to the exchange's operator through Mamlaka's secure channel, never by email or chat. They are entered on the server and are not stored anywhere else.
How the exchange behaves
These are the commitments the exchange makes to Mamlaka and to its own users. The full set is on The rules every rail keeps.
- One key per payment. The
externalIdis stored before the call. If the answer is lost, the exchange asks for the status of that same key; it never sends a second payment with a new key to "try again". - No answer is not a refusal. A timeout, a 5xx or an HTTP 202 leaves the payment Unknown. Money is held, never refunded, until
GET /transactionsays what happened. - A callback is a prompt to look. On every callback the exchange reads the transaction back from the gateway and acts on that answer, not on the callback body. A background poller does the same for any payment still open, so nothing depends on a callback arriving.
- Two people approve every payment out. B2C and card loads wait for two different Finance users. See Approvals and transfers.
- Sandbox safety. In the sandbox the exchange only lets the gateway's published test numbers through.
Next: Callbacks and webhooks, then the Go-live checklist.