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

# Webhook - Handling best practices

> Best practices for webhook handling: idempotency, fast responses, security, and more.

## Use the SDK built-in WebhookHandler

We strongly recommend using the SDK method `webhook().handleWebhook()`, which automatically handles:

* Signature verification
* JSON parsing and event routing
* Response body construction and signing

```typescript theme={null}
const handler = waffo.webhook()
  .onPayment((n) => handlePayment(n))
  .onRefund((n) => handleRefund(n))
  .onSubscriptionStatus((n) => handleSubscription(n))
  .onSubscriptionChange((n) => handleChange(n));

app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
  const result = await handler.handleWebhook(req.body.toString(), req.headers['x-signature'] as string);
  res.setHeader('X-SIGNATURE', result.responseSignature);
  res.status(200).send(result.responseBody);
});
```

## Idempotent handling

Waffo may deliver the same event multiple times. Make sure your handling logic is idempotent:

```typescript theme={null}
waffo.webhook().onPayment(async (notification) => {
  const orderId = notification.acquiringOrderId;

  const order = await db.order.findByAcquiringOrderId(orderId);
  if (order.status === 'PAY_SUCCESS') {
    return;
  }

  await updateOrderStatus(orderId, notification.orderStatus);
});
```

## Fast responses

* The SDK automatically builds the response after the handler finishes executing
* Time-consuming operations (such as sending emails or updating external systems) should be handled asynchronously
* If an exception is thrown in the handler, the SDK automatically returns a failure response

## Security

* Always verify `X-SIGNATURE` (handled automatically by the SDK)
* Use an HTTPS endpoint
* **Verify the signature before processing the event**—do not execute any business logic before verification passes
* The response must include the `X-SIGNATURE` header (handled automatically by the SDK)
