Skip to Content

Webhooks

Use webhooks to get transaction updates automatically.

Overview

Wakapay sends HTTP POST to your server when transaction status changes.

This avoids constant polling.

Configuration

Contact Wakapay account manager and provide:

  • Webhook URL (must be HTTPS)
  • Environment (Test or Production)
  • Signature mode (Current or Legacy)

Webhook Security

Current Signature Method (Default)

To validate the webhook signature, you’ll need to recompute it on your side using your business credentials along with the wakapayReference provided in the webhook payload.

Here’s the step-by-step process:

  1. Construct a string in the following exact format: apiKey:apiSecret
  2. Generate a SHA-256 hash of this string
  3. Hex-encode the resulting hash
  4. Compare your computed value with the signature field received in the webhook payload (A case-insensitive comparison is recommended)

Node.js Example

const crypto = require("crypto"); function validateWebhookSignature(apiKey, apiSecret, receivedSignature) { const raw = `${apiKey}:${apiSecret}`; const expected = crypto.createHash("sha256").update(raw).digest("hex"); return expected.toLowerCase() === (receivedSignature || "").toLowerCase(); }

Python Example

import hashlib def validate_webhook_signature(api_key, api_secret, received_signature): raw = f"{api_key}:{api_secret}" expected = hashlib.sha256(raw.encode()).hexdigest() return expected.lower() == (received_signature or "").lower()

Legacy Signature Method

Legacy only (older integrations)

Use only if Wakapay told this partner to use it.

  • Header: X-Wakapay-Signature
  • Format: t=<timestamp>,v1=<hmac>

Webhook Event

Business API uses one event:

transaction.updated

Check status to know current transaction state.

Valid Transaction Statuses

Only these statuses are valid for Business API:

  • termination_pending
  • termination_success
  • termination_failure

Ignore all old status names like completed, failed, or processing.

Webhook Payload Format

{ "businessId": "019d487b-00a5-787a-8aec-a4e5d33689e3", "businessReference": "EXT-INV-2026-0001", "wakapayReference": "293cd2ed-2db3-11f1-8c14-0242ac120008", "status": "termination_success", "senderCurrency": "USD", "receiverCurrency": "KES", "senderAmount": 0.7751937984496124, "receiverAmount": 100, "signature": "a1b2c3d4e5f6..." }

Sample Webhooks

Success

{ "businessId": "019d487b-00a5-787a-8aec-a4e5d33689e3", "businessReference": "EXT-INV-2026-0001", "wakapayReference": "293cd2ed-2db3-11f1-8c14-0242ac120008", "status": "termination_success", "senderCurrency": "USD", "receiverCurrency": "KES", "senderAmount": 0.7751937984496124, "receiverAmount": 100, "signature": "a1b2c3d4e5f6..." }

Failure

{ "businessId": "019d487b-00a5-787a-8aec-a4e5d33689e3", "businessReference": "EXT-INV-2026-0002", "wakapayReference": "4f2e9c1a-8b7d-4e6f-9a0b-123456789abc", "status": "termination_failure", "senderCurrency": "USD", "receiverCurrency": "KES", "senderAmount": 0.78, "receiverAmount": 100, "signature": "..." }

How to Process Webhooks

  1. Receive webhook
  2. Verify signature
  3. Check if wakapayReference was already processed (to avoid duplicates)
  4. Update your transaction using businessReference
  5. Return HTTP 200 OK quickly

If status is still termination_pending, check transaction again using GET /business/transactions/{businessReference}.

Check Transaction Status (When Still Pending)

If webhook status is still termination_pending, query the transaction to get final status.

Request

GET <BASE_URL>/business/transactions/{businessReference}

Headers:

Authorization: Bearer <business-token>

Response 200

{ "wakapayReference": "019ce78b-b204-716c-95ca-737ee5ec1559", "businessReference": "EXT-INV-2026-0001", "status": "termination_success", "senderCurrency": "USD", "receiverCurrency": "KES", "senderAmount": 100.0, "receiverAmount": 13025.0, "createdAt": "2026-04-27T07:10:00Z", "updatedAt": "2026-04-27T07:12:10Z" }

Response 404

{ "error": "transaction not found" }

Best Practices

  • Verify signature before processing
  • Handle duplicate deliveries using wakapayReference
  • Return 200 OK quickly
  • Use HTTPS only
  • Keep logs for debugging

Troubleshooting

Signature validation fails

  • Use correct apiKey and apiSecret
  • String format must be exactly apiKey:apiSecret
  • Use SHA-256
  • Compare case-insensitive

Webhook not received

  • Check endpoint is public
  • Check valid HTTPS certificate
  • Confirm URL with Wakapay account manager

Too many retries/timeouts

  • Return 200 OK quickly
  • Move heavy work to background queue
Last updated on