Skip to content

Idempotency

Networks fail after the server acted as often as before. If you POST a charge, the connection drops, and you retry — did you charge once or twice? With idempotency keys, the question disappears.

How it works

Every POST that creates something takes an Idempotency-Key header (it’s required on POST /v1/payments). The key is any string up to 255 characters that uniquely identifies the attempt — an order id is usually perfect.

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" }'
  • Same key + same body → you get the original response back, replayed. No second charge, ever. Safe to retry as hard as you like.
  • Same key + different body409 idempotency_key_reused. You almost certainly have a bug; we refuse rather than guess which body you meant.
  • Same key while the first attempt is still running409 request_in_progress. Back off and retry; you’ll get the replay.

Keys are held for 24 hours.

References are a second net

Independently of idempotency, every payment carries your reference, and a reference is unique per merchant. Reusing one returns 409 reference_in_use with the existing payment to fetch instead. Between the two mechanisms, “charged twice because we retried” is not a failure mode a Lango integration has.

The rule of thumb

Generate the key where the intent originates (your order id, your invoice number), not at the HTTP call site. Then any layer of your stack can retry safely — job queues, load balancers, a user mashing F5 — and the worst case is always the same response twice, never the same charge twice.