POST requests with a JSON body whenever a resource changes state. This page is the event catalog plus the delivery contract — payloads, signatures, retries, and deduplication. For registering endpoints and operational setup, see the webhooks guide.
Event envelope
Every delivery uses the same envelope; the event-specific object lives underdata, and the globally unique event_id is your deduplication key (see below):
Event types by resource
Payment events
payment.settled
Settlement events
settlement.completed
merchant_amount always equals gross_amount — the 5% fee is charged to the operator’s credit line, never deducted from the merchant. See Fees.
Agent events
agent.aml_declined
agent.aml_declined as terminal — subsequent payments from this agent return AML_DECLINED. See AML Screening.
Merchant events
merchant.kyb.approved
Verifying signatures
Every delivery includesSohopay-Signature — a hex-encoded HMAC-SHA256 of ${timestamp}.${raw_body} using your endpoint’s signing secret — and Sohopay-Timestamp, the Unix seconds when it was signed. Verify before parsing: recompute the HMAC over the timestamp and the raw request body (never re-serialized JSON), compare in constant time, and reject deliveries older than 5 minutes to block replays.
Delivery, retries, and deduplication
Respond with any2xx within 10 seconds to acknowledge a delivery. Anything else — a 4xx, 5xx, or timeout — triggers retries at 5s, 30s, 2m, 10m, 1h, then hourly up to 24 hours, after which the delivery is dropped.
Retries and network races mean the same event can arrive more than once, so dedupe by event_id: record each processed ID (a unique-constrained column, or a Redis SETNX with a TTL beyond 24 hours) and acknowledge duplicates with a 200 without reprocessing. Ordering is not guaranteed either — a payment.settled can arrive before its payment.created — so key state transitions on resource status, not event arrival order.
Acknowledge fast, process async: verify the signature, persist the event, return 200, then handle it from a queue. Slow handlers cause timeouts, which cause retries, which cause the duplicates you then have to dedupe.
Next steps
Webhooks Guide
Register endpoints, get signing secrets, and send test events.
Error Reference
The error codes behind payment.failed events.

