Skip to content

Direct API

If you collect the customer’s EcoCash number in your own product (a delivery app, a utility’s own portal), charge directly: one call with customer.msisdn, and the PIN prompt goes to the phone immediately.

Terminal window
curl https://api.lango.co.zw/v1/payments \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Idempotency-Key: order-4417" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "USD",
"method": "ecocash",
"reference": "ORD-4417",
"customer": { "msisdn": "263771234567" },
"metadata": { "order_id": "4417", "depot": "harare-north" }
}'

The response is awaiting_customer: the prompt is on their phone. From here:

  • Listen for the webhook (payment.succeeded / payment.failed / payment.expired) — the right way; or
  • Poll GET /v1/payments/{id} — acceptable for low volume; back off to every few seconds.

Your responsibilities in this mode

Because your UI owns the experience, the checkout page’s protections become your job:

  1. Show the fee before charging if your customer bears it. charged_amount in the create response (or preview beforehand) is the number they must see. Surprising people on the PIN prompt kills conversion and trust.
  2. Handle unknown honestly. “We’re confirming with EcoCash — don’t pay again.” Never “failed” while it’s still unknown. The whole page on this is required reading for direct integrations.
  3. Tell them to check their phone — with the masked number (customer_msisdn_masked in the response) and a countdown matching the payment’s expires_at.
  4. Validate numbers loosely, submit strictly. Accept 0771 234 567 from humans; send 263771234567. Lango normalises common Zimbabwean formats and rejects what can’t be a Zimbabwean mobile number, with a human-readable message you can show verbatim.

Metadata

metadata stores up to your own JSON object on the payment and comes back on every read and webhook — use it for your internal ids so reconciliation is a lookup, not a join.

Listing and pagination

GET /v1/payments?limit=25&starting_after=pay_... pages newest-first. Filters: status, method, currency, and search (matches references). The dashboard’s payment list is this endpoint.