Skip to main content

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

EventWhen
withdrawal.pendingPayout accepted
withdrawal.processingConversion / MoMo in progress
withdrawal.completedGHS delivered
withdrawal.failedPayout failed

Payment intent events

EventWhen
payment_intent.pending_approvalIntent created, awaiting consumer
payment_intent.approvedConsumer approved
payment_intent.completedSettled
payment_intent.rejectedConsumer declined
payment_intent.cancelledMerchant cancelled
payment_intent.expiredTTL elapsed
payment_intent.failedProcessing 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

PropertyValue
Timeout10 seconds per attempt
RetriesUp to 3 with backoff (~1s, 4s, 16s)
SuccessHTTP 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.