Overview
This page documents edge cases, failure modes, and Daya’s guarantees when things don’t go as planned.Deposit Timing Edge Cases
Late Deposits (After Onramp Expiry)
Scenario: User transfers NGN after the 25-minute onramp window What happens:- Deposit detected in virtual account
- Status immediately set to
FLAGGED flag_reason:"Deposit received after onramp expiry"- NGN held in suspense (not automatically processed)
- Webhook:
deposit.flagged
- Requires manual operations review (1-2 business days)
- Ops may process at current rate (not original rate_id)
- Or ops may reverse NGN to sender’s bank
- Inform user their deposit is under review
- Set expectation: 1-2 business days
- Provide support contact
Late Deposits (After Rate Expiry)
Scenario: User transfers after therate_id expires (but onramp still active)
What happens:
- Same as onramp expiry:
FLAGGED flag_reason:"Deposit received after rate expiry"
Deposit Before Onramp Fully Provisioned
Scenario: User transfers NGN before virtual account is fully activated (rare) What happens:- Deposit may be delayed or rejected by payment provider
- If received, processed normally once VA is active
- Show VA details only after onramp creation response received
- Do not display VA details during loading state
FX Conversion Edge Cases
No Valid Rate Available
Scenario: FX venue is temporarily unavailable Impact:GET /v1/ratesreturns 503 errorPOST /v1/onrampfails withrate_unavailable
- Show user-friendly error: “Exchange rates temporarily unavailable”
- Retry after 1-5 minutes
- Alert your operations team if persists > 15 minutes
FX Execution Failure
Scenario: FX conversion fails (no liquidity, internal error) What happens:- Deposit status →
FAILEDorFLAGGED(depending on cause) - NGN held in clearing account
- Webhook:
deposit.failedordeposit.flagged
| Cause | Status | Resolution |
|---|---|---|
| Temporary liquidity issue | FLAGGED | Retry automatically or manually |
| Permanent liquidity issue | FAILED | Reverse NGN to sender |
| Internal error | FLAGGED | Manual review |
- For
FAILED: Inform user to retry with new onramp - For
FLAGGED: Inform user of review (1-2 days)
On-Chain Withdrawal Edge Cases
Gas Price Spike
Scenario: Ethereum gas prices spike during withdrawal What happens:- Withdrawal may be delayed until gas prices normalize
- Deposit stays in
PENDING_WITHDRAWALlonger than usual - Eventually settles when gas becomes reasonable
- Show estimated wait time based on
chain - If > 15 minutes, alert operations
Chain Outage
Scenario: Target blockchain has downtime (network issues, hard fork, etc.) What happens:- Deposit status →
FLAGGEDor remainsPENDING_WITHDRAWAL - No on-chain broadcast until chain recovers
- Manual retry by operations once chain is healthy
- Check chain status (e.g., basescan.org status page)
- Inform user of network delay
- Provide estimated resolution time (if known)
Invalid Destination Address
Scenario: Destination address is invalid for specified chain What happens:- Caught at onramp creation time
POST /v1/onrampreturns error
- Validate address format client-side before submitting
- Use blockchain libraries (ethers.js, web3.js)
Withdrawal Rejected by Risk Engine
Scenario: Risk engine flags withdrawal What happens:- Deposit status →
FLAGGED - NGN and converted USD held
- Manual ops review required
- Destination address on sanctions list (future)
- Unusual velocity (many deposits to same address)
- Merchant under investigation
- Contact support with
deposit_id - Provide context if known legitimate use
Bank Reversal
Scenario: Sending bank reverses the original NGN transfer (rare) What happens:- Daya receives reversal notification
- If deposit already
SETTLED→ status changes toREVERSED - If deposit not yet settled → status changes to
FAILEDorFLAGGED
- If payout already sent on-chain: Daya absorbs the loss (v0.1)
- Merchant not charged back (v0.1)
- May affect merchant’s risk score
- Potential merchant liability for reversals
- Insurance or reserves to cover reversals
- None required (Daya handles)
- If user claims legitimate reversal, contact support
Duplicate Deposits
Scenario: User accidentally transfers NGN twice to same VA For throwaway onramps:- First deposit → Processes normally →
SETTLED - Second deposit →
FLAGGED(throwaway should only receive one deposit) - Manual review required
- First deposit →
SETTLED - Second deposit →
SETTLED(multiple deposits expected)
Idempotency is based on bank’s
bank_reference, not amount. Two transfers of same amount are treated as separate deposits if bank_reference differs.Webhook Delivery Failures
Scenario: Your webhook endpoint is down or returns errors What happens:- Daya retries with exponential backoff
- Up to 10 retries over 24 hours
- After 24 hours, delivery marked as failed
- Monitor webhook endpoint health
- Set up alerts for failures
- Query
GET /v1/depositsto recover missed events
Merchant Account Frozen
Scenario: Merchant account is frozen (manually or automatically) Impact:- All new onramp creation blocked
- Existing onramps may be disabled
- No FX execution for new deposits
- No withdrawals
POST /v1/onrampreturns 403 error- Deposits on existing onramps →
FLAGGED
- Exceeded 1,000 onramps/day limit
- Manual freeze by operations (risk/compliance)
- Contact [email protected]
- Provide context and explanation
- Await manual review and unfreeze
Guarantees
What Daya Guarantees
Firm quotes (throwaway onramps)
Firm quotes (throwaway onramps)
For deposits within validity window, the locked
rate_id is honored. No slippage.Atomicity
Atomicity
FX conversion and settlement are atomic. Either both succeed or both fail. No partial execution.
Idempotency
Idempotency
Duplicate bank transfers (same
bank_reference) create only one deposit. Webhooks may deliver multiple times but event_id ensures deduplication.Immutability
Immutability
Onramp settlement configuration cannot change after creation. Prevents unauthorized modification attacks.
At-least-once webhooks
At-least-once webhooks
Every deposit lifecycle event triggers at least one webhook delivery (may be multiple).
What Daya Does NOT Guarantee
Best Practices
1
Always verify webhook signatures
Prevent spoofing attacks by validating HMAC signatures.
2
Implement idempotency
Use
event_id and deposit_id to deduplicate events and deposits.3
Show clear error messages
For each failure mode, explain what happened and what the user should do.
4
Monitor for unusual delays
Alert operations if deposits stay in
PENDING_* states > 15 minutes.5
Design for eventual consistency
Don’t assume instant settlement. Use webhooks to know when deposits complete.