> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dintero.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook event subscriptions

> Receive real-time event notifications from Dintero by subscribing to webhooks via API or Backoffice for transactions, settlements, and other platform events.

A webhook is an HTTP request that Dintero sends to a URL you control whenever a subscribed event happens, such as a transaction being authorized or a settlement being created. Instead of polling the API for changes, your server receives the event data as soon as the event occurs.

Webhooks are configured per account and can deliver many event types. For events tied to a single Checkout session, you can also use the session `callback_url`. See [Validating callbacks](/docs/checkout/validating-callbacks) for that flow.

<Note>
  The `checkout_authorization` event delivers the same payload as the session `callback_url`. Use a webhook subscription when you want account-wide delivery instead of configuring a `callback_url` on every session.
</Note>

## Set up webhooks via API

Create a subscription with [POST /accounts/\{aid}/hooks/subscriptions](/webhooks-api/subscriptions/aid_source_hooks_post). In the request you define:

* `config.url` — the public HTTPS URL that receives the event payloads
* `events` — the list of event types to subscribe to
* `config.secret` — an optional secret used to sign deliveries (see [Verify event signature](#verify-event-signature))

When you create a subscription, Dintero sends a ping event so you can confirm the endpoint is set up correctly.

For the full list of event types and the payload of each, see the [Webhooks API reference](/webhooks-api/subscriptions/aid_source_hooks_post).

## Set up webhooks via Backoffice

In Dintero Backoffice, go to **Settings → Webhooks** to create and manage subscriptions without using the API.

## Verify event signature

To confirm that a request originated from Dintero, create the subscription with an `HMAC-SHA1` secret. Each delivery then includes an `event-signature` header containing the HMAC-SHA1 digest of the request body, computed with your secret.

<Note>
  The webhook subscription API signs deliveries with HMAC-SHA1. This is separate from the Checkout `callback_url` signature, which uses HMAC-SHA256. See [Validating callbacks](/docs/checkout/validating-callbacks).
</Note>

Compute the digest over the raw request body and compare it to the header value:

```typescript theme={null}
const crypto = require("node:crypto");

// `rawBody` must be the exact bytes received, not a re-serialized object.
// In Express, capture them with the json parser's `verify` hook:
//   express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } })
const verifyEventSignature = (rawBody, secret, eventSignature) => {
    if (typeof eventSignature !== "string") {
        return false;
    }

    const calculatedEventSignature = crypto
        .createHmac("sha1", Buffer.from(secret))
        .update(rawBody)
        .digest("hex");

    const received = Buffer.from(eventSignature, "hex");
    const calculated = Buffer.from(calculatedEventSignature, "hex");

    return (
        received.length === calculated.length &&
        crypto.timingSafeEqual(received, calculated)
    );
};
```

<Warning>
  Verify the signature against the **raw request body bytes**, exactly as received. Re-serializing the parsed JSON (for example with `JSON.stringify(req.body)`) can change whitespace or key order, producing a digest that does not match and rejecting legitimate deliveries.
</Warning>

<Tip>
  Decode both hex signatures to buffers and compare them with a constant-time function such as `crypto.timingSafeEqual` rather than `===`, so the check does not leak timing information. Guard against a missing header and unequal lengths first, since `timingSafeEqual` throws when the buffers differ in length.
</Tip>
