Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kler.africa/llms.txt

Use this file to discover all available pages before exploring further.

When a payment is received on a Kler collection account, Kler fires a POST request to the webhook_url you set when creating the session.

Event types

EventWhen it fires
transaction.receivedA payment has been recorded on the session
More event types (e.g. session.closed, terminal.offline) will be added over time.

Payload

{
  "event": "transaction.received",
  "session_id": "sess_...",
  "data": {
    "id": "txn_...",
    "amount": "5000.00",
    "currency": "NGN",
    "channel": "bank_transfer",
    "status": "successful",
    "sender_name": "Jane Doe",
    "sender_account": "0123456789",
    "sender_bank": "058",
    "narration": "Ticket purchase",
    "providus_ref": "PVS20250801XXXXXXX",
    "paid_at": "2025-08-01T18:32:00.000Z"
  }
}

Channel values

ValueMeaning
bank_transferNIP / instant bank transfer
posPOS terminal
ussdUSSD payment
cardWeb/card payment

Handling webhooks

Your endpoint should:
  1. Return a 200 response quickly — Kler does not wait for your processing to complete
  2. Process the event asynchronously if needed
  3. Be idempotent — the same transaction.id may be delivered more than once
app.post('/webhooks/kler', async (req, res) => {
  res.status(200).send({ received: true }) // respond immediately

  const { event, session_id, data } = req.body

  if (event === 'transaction.received') {
    await recordPayment(session_id, data)
  }
})

Retries

If your endpoint does not return a 2xx response, Kler will retry the webhook with exponential backoff up to 5 times.