Partner API Webhooks
Webhooks deliver real-time events to your HTTPS endpoint. Prefer webhooks over polling in production.
Register endpoints in Fiatsend Console (Settings → Webhooks) or via POST /v1/webhooks.
Withdrawal events
| Event | When |
|---|---|
withdrawal.pending | Payout accepted |
withdrawal.processing | Conversion / MoMo in progress |
withdrawal.completed | GHS delivered |
withdrawal.failed | Payout failed |
Payment intent events
| Event | When |
|---|---|
payment_intent.pending_approval | Intent created, awaiting consumer |
payment_intent.approved | Consumer approved |
payment_intent.completed | Settled |
payment_intent.rejected | Consumer declined |
payment_intent.cancelled | Merchant cancelled |
payment_intent.expired | TTL elapsed |
payment_intent.failed | Processing failed |
Payload envelope
{
"id": "evt_3nRpK8wZqMvY",
"type": "withdrawal.completed",
"created_at": "2026-04-02T05:01:20Z",
"data": {
"withdrawal_id": "wdl_9k2mX7pQrLzT",
"status": "completed",
"amount": "50.00",
"currency": "USDT",
"recipient_phone": "+233501234567",
"mobile_network": "MTN",
"ghs_amount": "764.50",
"reference_id": "payout-001"
}
}
Signature verification
Header: X-Fiatsend-Signature: sha256=<hex>
Compute HMAC-SHA256 of the raw request body using your webhook secret, prefix with sha256=, and compare with constant-time equality.
import crypto from "crypto";
function verifyWebhook(rawBody, signatureHeader, secret) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
warning
Use the raw body (before JSON parsing). Respond with HTTP 2xx within ~10 seconds and process asynchronously.
Register via API
curl -X POST https://sandbox.fiatsend.com/v1/webhooks \
-H "Authorization: Bearer $FIATSEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.yourapp.com/webhooks/fiatsend",
"events": ["withdrawal.completed", "withdrawal.failed"],
"secret": "your_webhook_secret"
}'
Delivery and retries
| Property | Value |
|---|---|
| Timeout | 10 seconds per attempt |
| Retries | Up to 3 with backoff (~1s, 4s, 16s) |
| Success | HTTP 2xx from your server |
View delivery logs: GET /v1/webhooks/{webhook_id}/deliveries or Console Delivery Logs.
Deduplicate using event id — the same event may be delivered more than once.
Related
- REST SDK — built-in verification helpers
- Errors & rate limits