What are Webhooks?
Webhooks allow you to receive real-time HTTP notifications when deposit lifecycle events occur, eliminating the need to poll the API.Webhooks are the recommended way to track deposit status changes. They provide better user experience and reduce API load.
Supported Events
| Event | Description | When Triggered |
|---|---|---|
deposit.created | Deposit detected | NGN received in virtual account |
deposit.settled | Deposit fully settled | On-chain tx confirmed or balance credited |
deposit.failed | Deposit permanently failed | FX failure, on-chain error, or validation error |
deposit.flagged | Deposit held for review | Late deposit, limits exceeded, or risk trigger |
Webhook Configuration
Configure webhook endpoints in your Daya Dashboard:- Navigate to Webhooks section
- Add webhook URL (must be HTTPS)
- Generate webhook secret
- Select events to subscribe to
Webhook Payload
All webhook events follow this structure:Common Fields
Event typeValues:
deposit.created, deposit.settled, deposit.failed, deposit.flaggedUnique identifier for this webhook deliveryUse for: Idempotency (deduplicate multiple deliveries)
When event occurred (ISO 8601 timestamp)
Event-specific data (varies by event type)
Event-Specific Payloads
- deposit.created
- deposit.settled
- deposit.failed
- deposit.flagged
Sent when: NGN deposit detected in virtual accountNext steps: Monitor for
deposit.settled or deposit.failedDelivery Guarantees
At-least-once delivery
At-least-once delivery
Webhooks may be delivered multiple times. Your endpoint must handle duplicate deliveries using
event_id for idempotency.Order not guaranteed
Order not guaranteed
Events may arrive out of order. Use
created_at timestamps to order events client-side.Retry behavior
Retry behavior
If your endpoint returns non-2xx status or times out (10 seconds), Daya retries with exponential backoff:
- Retry 1: After 1 minute
- Retry 2: After 5 minutes
- Retry 3: After 30 minutes
- Retry 4-10: Every hour (up to 24 hours total)
Timeout
Timeout
Your endpoint must respond within 10 seconds. Longer responses will timeout and trigger retries.
Webhook Verification
All webhooks include an HMAC-SHA256 signature in theX-Daya-Signature header. Always verify signatures to prevent spoofing.
See Webhook Verification for implementation details.
Implementing a Webhook Endpoint
Required Response
Your endpoint must:- Verify signature (see Verification)
- Return 2xx status to acknowledge receipt
- Process quickly (< 10 seconds) or queue for async processing
Example Implementation
Best Practices
1
Verify signatures
Always verify
X-Daya-Signature to prevent spoofing attacks.2
Handle idempotency
Use
event_id to deduplicate. Store processed event IDs in your database.3
Return 200 quickly
Acknowledge receipt immediately (< 1 second). Queue heavy processing asynchronously.
4
Handle out-of-order delivery
Use
created_at timestamps to order events correctly.5
Monitor webhook health
Track failed deliveries in your dashboard and set up alerts.
6
Test with sandbox
Use sandbox environment to test webhook handling before production.
Testing Webhooks
Sandbox Testing
In sandbox, trigger test webhooks:- Create test onramp
- Simulate deposit via dashboard or test API
- Receive webhook at your endpoint
Local Testing
For local development, use tools like ngrok:Troubleshooting
Webhooks not received
Webhooks not received
Possible causes:
- Firewall blocking Daya’s IPs
- Endpoint returning non-2xx status
- SSL certificate issues
Duplicate deliveries
Duplicate deliveries
Expected behavior: At-least-once delivery means duplicates are possibleFix: Implement idempotency using
event_idTimeouts
Timeouts
Cause: Endpoint taking > 10 seconds to respondFix: Return 200 immediately, queue processing asynchronously
Signature verification fails
Signature verification fails
Cause: Wrong secret or payload manipulationFix: Verify you’re using correct webhook secret from dashboard