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

# Best Practices

> Recommendations for reliable webhook handling.

# Webhook Best Practices

## 1. Respond Fast

Return `200 OK` within 5 seconds. Process the event asynchronously after acknowledging:

```javascript theme={null}
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  res.status(200).send('OK');           // Acknowledge immediately
  const payload = JSON.parse(req.body); // Process in background
  processEvent(payload);
});
```

## 2. Handle Duplicates

Use the `event_id` field (also sent as the `X-Khaime-Event-Id` header) for idempotency. The same event may be delivered more than once — retries reuse the same `event_id`:

```javascript theme={null}
async function handleEvent(payload) {
  const { event_id } = payload;

  // Use a database or Redis — not in-memory sets
  const alreadyProcessed = await redis.get(`webhook:${event_id}`);
  if (alreadyProcessed) return;

  await redis.set(`webhook:${event_id}`, '1', 'EX', 86400); // TTL: 24h
  // Process...
}
```

## 3. Verify Before Processing

Always [verify the signature](/webhooks/verification) using the **raw request body** before acting on a webhook. Reject unverified requests with `401`.

## 4. Handle Missing Events

If a webhook is missed and you used the Sessions API, you can check the payment status directly:

```bash theme={null}
# Check session status (Sessions API only)
GET /api/v1/partner/payments/sessions/{session_id}
```

For payments created via the Charge API, webhook delivery is the only confirmation mechanism. Ensure your webhook endpoint is reliable and returns `200` promptly.

## 5. Use the Envelope Fields

Every webhook includes useful envelope fields beyond the event data:

* **`api_version`** — confirms which payload schema version was used
* **`is_live`** — distinguish sandbox events from production
* **`business_id`** — identify which merchant the event belongs to (useful in marketplace setups)

## 6. Log Everything

Log raw webhook payloads for debugging. Include the `event_id`, `event_type`, and processing result.

## 7. Use HTTPS

Webhook URLs must use HTTPS in production. Khaime will not deliver webhooks to HTTP endpoints in live mode.

## 8. Plan for New Event Types

New event types may be added without a version change. Your webhook handler should gracefully ignore unknown `event_type` values rather than erroring:

```javascript theme={null}
switch (payload.event_type) {
  case 'payment.succeeded':
    handlePaymentSucceeded(payload.data);
    break;
  case 'payment.refunded':
    handlePaymentRefunded(payload.data);
    break;
  // ... other known events
  default:
    console.log(`Unhandled event type: ${payload.event_type}`);
}
```
