Uverus Payments

Webhooks

Receive real-time notifications for events.

Webhooks

Webhooks let your system receive real-time updates when events happen on Uverus, instead of polling for status.

Headers

HeaderRequiredValue
AuthorizationYesBearer sk_test_... (test) or Bearer sk_live_... (live) — see Authentication

Setting Up

You can manage webhook endpoints from Settings → Webhooks in the dashboard, or via the API below. Either way, once an endpoint is registered, Uverus sends a POST request to it whenever a subscribed event occurs.

Register an Endpoint

POST /api/v1/merchant-webhooks

Request Body

FieldTypeRequiredDescription
urlstringYesYour endpoint URL. Must be http(s)://.
eventsstring[]NoEvent names to subscribe to. Omit (or pass ["*"]) to receive every event.

Example Request

curl -X POST "https://api.uveruspayments.com/api/v1/merchant-webhooks" \
     -H "Authorization: Bearer sk_test_..." \
     -H "Content-Type: application/json" \
     -d '{ "url": "https://your-api.com/webhooks/uverus" }'

Example Response

{
  "id": "uuid",
  "merchantId": "uuid",
  "url": "https://your-api.com/webhooks/uverus",
  "secret": "whsec_...",
  "events": "*",
  "isActive": true,
  "mode": "test",
  "successCount": 0,
  "failureCount": 0,
  "lastDeliveredAt": null,
  "createdAt": "2026-08-27T10:00:00.000Z"
}

Important

secret is only ever shown in full via this response and in the dashboard. Save it — you'll need it to verify signatures below.

List Endpoints

GET /api/v1/merchant-webhooks

Returns every webhook endpoint registered for the authenticated merchant and mode.

Remove an Endpoint

DELETE /api/v1/merchant-webhooks/{id}

Send a Test Event

Fires a test.event payload at your endpoint immediately, using the real signing and delivery path — useful for confirming your handler and signature verification work before going live.

POST /api/v1/merchant-webhooks/{id}/test

Event Types

EventDescription
checkout.successA customer completed a checkout payment successfully.
checkout.failedA checkout payment failed.
transfer.successAn outbound transfer was delivered to the recipient.
transfer.failedAn outbound transfer failed; funds were returned to your Transfer wallet.

Payload Structure

{
  "event": "checkout.success",
  "data": {
    "reference": "uvr_123456",
    "amount": 500000,
    "currency": "NGN",
    "status": "completed",
    "customerEmail": "customer@example.com"
  },
  "timestamp": "2026-08-27T10:15:00.000Z",
  "webhookId": "uuid"
}

Every delivery also carries these headers:

HeaderDescription
X-Uverus-SignatureHMAC-SHA256 signature of the raw request body — see below
X-Uverus-EventThe event name, matching the event field in the body
X-Uverus-Webhook-IdThe ID of the webhook endpoint that was triggered
X-Uverus-AttemptDelivery attempt number (retries up to 3 times on failure)

Security (HMAC Verification)

Every payload is signed with your endpoint's secret (from registering the endpoint). Verify the X-Uverus-Signature header to confirm a request actually came from Uverus:

const crypto = require('crypto');

const signature = request.headers['x-uverus-signature'];
const expected = crypto
  .createHmac('sha256', YOUR_WEBHOOK_SECRET)
  .update(rawRequestBody) // the exact raw bytes received — not a re-serialized JSON.stringify(req.body)
  .digest('hex');

if (expected === signature) {
  // Request is authentic
}

Important

Compute the signature over the raw request body, before your framework parses it into an object. Re-serializing a parsed body can reorder keys or change whitespace, producing a signature that never matches.

On this page