Pandabase
Ledger

Events and webhooks

Receive notifications when accounts, transactions, and other ledger records change.

Ledger is in alpha. There are no Ledger fees during alpha.

Ledger saves an event whenever a record changes. The event and the change are saved together in the same database transaction.

An event's data shows the resource at the time of that change. Fetch the resource again if your application needs its latest state.

Event types

TypeSent when
account.created, account.updatedAn account is created or changed, including status changes.
transaction.createdA transaction is created, including ones created posted.
transaction.updatedA pending transaction is edited.
transaction.postedA pending transaction is posted.
transaction.archivedA transaction is archived.
hold.created, hold.captured, hold.voided, hold.expiredA hold changes.
balance_monitor.triggeredA balance monitor's condition becomes true.
bulk_request.completedA bulk request finishes.
settlement.createdA settlement is created.

Events are kept for 30 days. Use them to react to changes, and use ledger entries for the accounting history.

Webhook endpoints

Register an HTTPS URL to receive events as JSON POST requests. Choose which events to receive with event_types, using exact names like hold.captured, patterns like transaction.*, or * for everything.

{
  "url": "https://example.com/webhooks/ledger",
  "event_types": ["transaction.*", "hold.captured"],
  "description": "Payments service"
}

Creating an endpoint returns a signing secret that starts with whsec_. It's only shown once, so save it then.

Receive events

The same event can arrive more than once, and events can arrive out of order. Track event IDs so you don't process a duplicate twice.

Return a 2xx response once you've accepted the event. Any other status, a network error, or no response within 10 seconds counts as a failed attempt.

Verify signatures

Read the raw request body before parsing the JSON.

Extract t and v1 from the signature header, which looks like t=1788220800,v1=<hex signature>.

Compute an HMAC-SHA256 of <t>.<raw body>, using the entire secret string, including whsec_, as the key.

Compare the lowercase hex digest with v1 using a constant-time comparison.

Reject timestamps outside your tolerance, such as five minutes, and deduplicate by event ID.

Retries

A failed delivery is retried 11 times after the first attempt, over roughly three days: after 1 minute, 5 minutes, 30 minutes, 1 hour, 2 hours, 5 hours, 10 hours, 10 hours, 12 hours, 12 hours, and 12 hours. Each attempt gets a fresh timestamp and signature. You can also request another attempt for a failed delivery yourself.

Last updated on

On this page