Skip to main content
Danipa

Error Handling

HTTP status codes, error response format, and common error codes for the Danipa Payment API.

Error Response Format

All API errors return a consistent JSON structure:

{
  "error": {
    "code": "INVALID_AMOUNT",
    "message": "Amount must be greater than zero",
    "details": {
      "field": "source.amount",
      "constraint": "minimum",
      "value": 0
    }
  },
  "request_id": "req_abc123",
  "timestamp": "2026-03-11T14:22:00Z"
}

HTTP Status Codes

CodeMeaningWhen
200OKSuccessful GET request
201CreatedResource successfully created
202AcceptedAsync operation accepted (e.g., remittance)
400Bad RequestInvalid parameters or malformed JSON
401UnauthorizedMissing or invalid API key
403ForbiddenValid API key but insufficient permissions
404Not FoundResource does not exist
409ConflictDuplicate X-Request-Id (idempotency)
422UnprocessableValid JSON but business rule violation
429Too Many RequestsRate limit exceeded
500Server ErrorUnexpected server error
503Service UnavailableMaintenance or provider outage

Common Error Codes

Validation Errors (400)

CodeDescription
INVALID_AMOUNTAmount is zero, negative, or exceeds limits
INVALID_CURRENCYUnsupported currency code
INVALID_MSISDNPhone number is not valid E.164 format
INVALID_PROVIDERUnsupported payout provider
MISSING_FIELDRequired field not provided

Business Errors (422)

CodeDescription
INSUFFICIENT_BALANCEWallet balance too low for this transaction
DAILY_LIMIT_EXCEEDEDTransaction would exceed daily sending limit
RECIPIENT_NOT_FOUNDMoMo account not registered for this number
CORRIDOR_UNAVAILABLECurrency pair not currently supported
KYC_REQUIREDHigher KYC tier needed for this amount

Provider Errors (502/503)

CodeDescription
PROVIDER_TIMEOUTMoMo or bank API did not respond in time
PROVIDER_UNAVAILABLEPayout provider is temporarily down
PROVIDER_REJECTEDProvider rejected the transaction

Retry Strategy

Error TypeRetry?Strategy
400 (validation)NoFix the request and resubmit
401/403 (auth)NoCheck API key and permissions
404 (not found)NoVerify the resource ID
409 (conflict)NoUse a different X-Request-Id
429 (rate limit)YesWait for Retry-After header
500 (server)YesRetry with exponential backoff
502/503 (provider)YesRetry after 30-60 seconds

Idempotency

All POST requests require an X-Request-Id header. If you send the same X-Request-Id twice, the second request returns the original response without creating a duplicate transaction.

# First request — creates the transaction
curl -X POST .../remittance -H "X-Request-Id: req-001" ...
# => 202 Accepted, txn_abc123

# Retry with same ID — returns the same transaction
curl -X POST .../remittance -H "X-Request-Id: req-001" ...
# => 200 OK, txn_abc123 (no duplicate created)

Idempotency keys expire after 24 hours.