Webhooks
Webhooks let your server find out about a successful payment the moment it happens, instead of polling. Configure your endpoint URL from the merchant dashboard.
What fires today
There is currently one event: charge.completed, sent when a charge's status becomes completed. It is a single HTTP POST to the URL you configured.
Payout events are not sent yet
The dashboard lets you configure a webhook for payout events, but nothing currently triggers it — no payout notification is sent today. Only build against
charge.completed until this changes.Payload
POST to your endpoint
{
"event": "charge.completed",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"reference": "inv_881",
"amount": 15000,
"fee_amount": 225,
"net_amount": 14775,
"currency": "XAF",
"completed_at": "2026-10-02T10:18:42Z"
}
}data.amountintegeroptional | The full amount the customer paid. |
data.fee_amountintegeroptional | LotiFinance's processing fee, already deducted from amount. |
data.net_amountintegeroptional | amount minus fee_amount — what was credited to your balance. |
Verifying the signature
Every request includes an X-LotiFinance-Signature header: an HMAC-SHA256 hex digest of the exact request body, signed with your webhook's signing secret (shown once when you create the webhook in the dashboard).
verify.js
import crypto from "crypto";
function isValidSignature(rawBody, signatureHeader, signingSecret) {
const expected = crypto
.createHmac("sha256", signingSecret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
}Compute the HMAC over the raw request body — before any JSON parsing — or the signature won't match.
Delivery behavior
- Delivery is fire-and-forget with an 8 second timeout.
- There are no retries. If your endpoint is down or times out, the event is not redelivered. Treat polling via
GET /v1/charges/{id}/as your source of truth, and use the webhook purely as a low-latency notification. - Respond quickly with a 2xx status — do heavy processing asynchronously after acknowledging receipt.