LLedgerline DocsAPI v2.4Want docs like this? Talk to Doc Foundry

API reference / Webhooks

Webhooks

Ledgerline sends an HTTPS POST to your endpoint when something happens on your account, such as a payment succeeding. Use webhooks to fulfil orders instead of waiting on the customer's redirect.

Set up an endpoint

  1. Create a route on your server that accepts POST requests with a JSON body.
  2. Add its URL in Dashboard → Developers → Webhooks, and copy the signing secret it shows you (it starts with whsec_).
  3. Verify every request's signature before you act on it, as shown below.
  4. Return any 2xx status within 10 seconds. Do slow work, such as sending emails, after you respond.

Events

EventSent when
payment.processingThe customer has paid and the bank is confirming.
payment.succeededFunds are confirmed. Fulfil the order on this event.
payment.failedThe payment failed or expired.
refund.succeededA refund has reached the customer's bank.
payout.paidA payout has landed in your settlement account.
Example payload · payment.succeededJSON
{
  "id": "evt_3Rk9QwZ1",
  "type": "payment.succeeded",
  "created_at": "2026-11-03T10:16:05Z",
  "data": {
    "id": "pay_7Hq2LmX9",
    "status": "succeeded",
    "amount": 250000,
    "reference": "order_1042"
  }
}

Verify the signature

Each request carries a Ledgerline-Signature header: a timestamp and an HMAC-SHA256 of timestamp.body, signed with your endpoint secret. Check it against the raw request body, before any JSON parsing changes it.

Verify a webhookNode.js
import crypto from 'node:crypto';

// header looks like: t=1762164965,v1=5f1c...
export function verify(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // older than 5 minutes
  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  return v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}
Reject anything that fails verification

Return 400 and do nothing else. Without this check, anyone who finds your endpoint can mark orders as paid.

Retries and duplicates

If your endpoint doesn't return 2xx in time, Ledgerline retries with increasing gaps: after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours. After the last attempt the event is marked failed, and you can resend it from the dashboard.

Because of retries, you may receive the same event more than once. Store each event.id you process and skip ones you've already handled.

Testing

From Dashboard → Developers → Webhooks, choose Send test event to deliver any event type to your sandbox endpoint. Test events are signed with your sandbox secret.

Last updated 3 November 2026