Skip to main content
Payments are event-driven. Once you create a payout, it may take seconds or days to complete depending on the payment method and banking networks involved. Webhooks let you:
  • Update internal records when payouts succeed or fail.
  • Trigger notifications to your team or payees.
  • Automate reconciliation and reporting.

Setting Up a Webhook Endpoint

A webhook endpoint is just an HTTPS URL on your server that can accept POST requests. When something happens — like a payout completing — Acclaim sends a JSON payload to your endpoint. Key considerations when building your endpoint:
  • Must accept POST requests with a JSON body.
  • Must return a 2xx HTTP status code to acknowledge receipt.
  • Should be idempotent (able to safely handle duplicate deliveries).
Example flow:
  1. Acclaim sends an event payload to your webhook URL.
  2. Your server processes the event.
  3. Your server responds with 200 OK to confirm receipt.

Installing Webhooks in the Console

You can install and manage webhook endpoints directly from the Acclaim Console under Settings → Developers → Webhooks.
  • Add one or more HTTPS URLs where Acclaim should send events.
  • Choose which event types to subscribe to, or receive all events by default.
  • Test delivery right from the console to verify your endpoint is working.

Event Payload Structure

All webhook events share a consistent format:
{
  "id": "evt_MjdYqzLbsS",
  "type": "payout.succeeded",
  "account_id": "acct_ovGlkewETl",
  "created_at": "2025-10-08T18:20:31Z",
  "data": {
      "id": "po_vkj7BPRPr9",
      "payee_id": "pyee_PXlpcv13X9",
      "payment_amount": 50000,
      "payment_currency": "usd"
      // truncated for brevity
  }
}
id
string
Unique event identifier.
type
string
Event type, such as payout.completed.
account_id
string
The account ID that generated the event.
created_at
datetime
Timestamp of the event.
data
object
The resource that changed (e.g., payout details). This will match the same format as retrieving the resource through the API.

Event Types

Payer Events

  • payer.created
  • payer.updated
  • payer.deleted

Payment Request Events

  • payment_request.created
  • payment_request.updated
  • payment_request.succeeded
  • payment_request.failed
  • payment_request.canceled

Tokenization Request Events

  • tokenization_request.created
  • tokenization_request.updated
  • tokenization_request.succeeded
  • tokenization_request.failed
  • tokenization_request.canceled

Refund Events

  • refund.created
  • refund.failed
  • refund.succeeded

Dispute Events

  • dispute.created

Payee Events

  • payee.created
  • payee.updated
  • payee.deleted

Payout Events

  • payout.created
  • payout.updated
  • payout.processing
  • payout.succeeded
  • payout.failed

Payout Batch Events

  • payout_batch.created
  • payout_batch.updated
  • payout_batch.succeeded
  • payout_batch.failed
  • payout_batch.canceled

Treasury Account Events

  • treasury.account.created
  • treasury.account.updated

Treasury Transaction Events

  • treasury.transaction.created

Reliability & Retries

Acclaim automatically retries failed webhook deliveries for up to 48 hours using exponential backoff. Your endpoint should:
  • Be idempotent: safely handle duplicate events.
  • Respond quickly: return 2xx as soon as the event is accepted, then process asynchronously if needed.
  • Log event ids to avoid reprocessing the same event.
If all retry attempts fail, the event will be marked as undelivered in the Acclaim Console.

Securing Webhooks

Webhooks should be secure so only Acclaim can call them:
  • Use HTTPS for encryption.
  • Verify the webhook signature before you process the event.

Signature verification

Each webhook request includes these headers:
  • Acclaim-Timestamp - The Unix timestamp used when the request was signed.
  • Acclaim-Signature - The HMAC signature for the request body, in the format v1=<hex_digest>.
Acclaim signs the exact request body bytes using HMAC SHA-256 and your webhook endpoint secret. To verify a webhook:
  1. Read the raw request body exactly as it was received.
  2. Read the Acclaim-Timestamp header.
  3. Build the signed payload as timestamp.raw_body, with a literal . between the timestamp and raw body.
  4. Compute an HMAC SHA-256 digest using your webhook endpoint secret.
  5. Prefix the digest with v1= and compare it to the Acclaim-Signature header using a constant-time comparison.
  6. Reject the request if the signature does not match.
Use the raw request body for verification. If your framework parses and re-serializes the JSON before verification, the signature check can fail.
Example verification flow in JavaScript:
import crypto from 'node:crypto';

const timestamp = req.header('Acclaim-Timestamp') ?? '';
const signatureHeader = req.header('Acclaim-Signature') ?? '';
const rawBody = req.rawBody;

const signedPayload = `${timestamp}.${rawBody}`;
const expectedSignature = crypto
  .createHmac('sha256', webhookSecret)
  .update(signedPayload, 'utf8')
  .digest('hex');
const expectedHeader = `v1=${expectedSignature}`;

if (!crypto.timingSafeEqual(Buffer.from(expectedHeader), Buffer.from(signatureHeader))) {
  res.status(400).send('Invalid signature');
  return;
}
For additional protection, you can also reject requests with old timestamps to reduce replay risk.

What’s Next

Once your webhook endpoint is live, test it using your sandbox environment. Create a payout and watch events arrive, confirming your system can react to status changes and keep your records up to date.
Last modified on April 8, 2026