webhookUrl.
What you set up
- Expose any public
POSTpath you want. The path is yours. Example:https://example.com/hooks. It must behttps://on a public host (not localhost, not an IP, nothttp). - Configure that full URL as your merchant
webhookUrlin your Demat dashboard. - Verify the signature with the same secret API key you already use for REST (
sk_test_...orsk_live_...). There is no separate webhook secret. Do not usepk_keys.
wallet.credited event as a live inbound transfer. It does not lock a hold.
Verify the signature
We sign the raw body with your secret key and send the hex digest asx-demat-signature:
Content-Type: application/json. x-demat-signature is the HMAC. x-demat-event is optional and matches body.type.
Respond with 2xx within a few seconds. We time out at 5 seconds and retry a failed delivery 3 times, 15 seconds apart. Deduplicate on body.id (evt_...).
Body
Every delivery uses the same shape. REST responses are unchanged. This is webhooks only.id is the event id (ignore a replay of the same evt_...). type is the event name. createdAt is when we created it. data is the resource snapshot (same fields as the matching GET). meta is event-only context and is always present ({} when there is nothing extra). Amounts are naira. Fields are camelCase.
data on escrow events matches GET /escrows/{id}. data.amount is the hold total. A release or refund puts this movement in meta.movementAmount.
Events we send
These are the events POSTed to yourwebhookUrl. Customer create does not send one. Treat this list as the catalog. Do not infer extra events. Payload shapes are shown in the examples below.
A dispute resolve also emits the matching
escrow.released / escrow.partially_released / escrow.refunded events from the money movement. Deduplicate on id.
escrow.refunded always means “this refund movement happened”. Final escrow data.status may be refunded, partially_released, or released depending on what was already released.
Example: escrow.created
Example: escrow.funded
Example: payment.succeeded
chargedAmount is the total the payer paid (what we sent to the provider). netAmount / amount is what funded the hold or wallet after provider, Demat platform, and optional merchant fees.
Example: escrow.released
Example: dispute.opened
Example: wallet.credited
meta.amount / meta.netAmount is what credited available. grossAmount is what the customer transferred; providerFee is the provider’s deposit fee. See Fees.
Do not expose sk_test_ or sk_live_ in client apps.