Skip to content

Hosted checkout

Hosted checkout is the integration most stores want: your backend creates the payment, the customer pays on checkout.lango.co.zw, and Lango handles the prompt, the polling, the timeouts and the copy — including the states that protect you from double charges.

The flow

  1. Create the payment without a customer number:

    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",
    "return_url": "https://yourstore.co.zw/orders/4417/thanks"
    }'

    Omitting customer.msisdn is what makes it hosted: the customer enters their own number on the checkout page, and the charge happens there.

  2. Redirect the customer to the checkout_url in the response (https://checkout.lango.co.zw/c/tok_...).

  3. The customer pays: they see your name, the amount, any customer-borne fee as its own line; they enter their EcoCash number; the PIN prompt lands on their phone with a visible countdown.

  4. You hear the outcome on your webhook (payment.succeeded / payment.failed), and the customer is offered the return_url back to you.

Rules worth knowing

  • Fulfil on the webhook, not the redirect. A customer can close the browser after paying; the webhook always arrives.
  • The checkout page expires unpaid payments after their window; the payment ends expired, with an event.
  • The page shows your trading name — set it in Dashboard → Settings before going live.
  • The checkout token in checkout_url grants access to that payment’s checkout view and nothing else. It cannot read your account.

What checkout does that you don’t have to

  • Shows the methods that are live right now. Omit method when you create the payment and the checkout page lets the customer choose from the current live catalogue (the same GET /v1/payment-methods). You never hard-code or maintain a method list — new rails appear and retired ones drop off on their own.
  • Zimbabwean number formatting and validation (263 7x ...).
  • The waiting screen with countdown, “check your phone”, and the masked number.
  • Timeout handling that distinguishes “declined” from “no answer yet” — the unknown discipline — with copy that stops customers paying twice.
  • Works with JavaScript disabled; under 50KB; no third-party scripts for a strict CSP.