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

# Webhooks

> Receive real-time order event notifications

Receive real-time notifications when POS order events occur.

## How Webhooks Work

When you create an order with a `callback_url`, Quickei sends an HTTP POST request to that URL whenever the order status changes. The payload is JSON-encoded and includes a signature header for verification.

## Signature Verification

Every webhook includes an `X-Quickei-Signature` header containing an HMAC-SHA256 signature of the request body, signed with your `client_secret`.

```
X-Quickei-Signature: sha256=HMAC_SHA256(payload, client_secret)
```

## Events

| Event                 | Trigger                      |
| --------------------- | ---------------------------- |
| `pos.order.paid`      | Customer completed payment   |
| `pos.order.expired`   | Order expired before payment |
| `pos.order.cancelled` | Order cancelled by merchant  |
| `pos.order.refunded`  | Payment refunded to customer |

## Example Payload

```json theme={null}
{
  "event": "pos.order.paid",
  "timestamp": "2024-01-15T14:02:30+00:00",
  "data": {
    "order_id": "POS-20240115-A1B2C3",
    "amount": 25.00,
    "currency": "EUR",
    "status": "PAID",
    "reference": "INV-2024-001",
    "terminal_id": "terminal-01",
    "trx_id": "TRX-98765",
    "paid_at": "2024-01-15T14:02:30+00:00"
  }
}
```

## PHP Verification Example

```php theme={null}
// Verify webhook signature
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_QUICKEI_SIGNATURE'];

$expected = 'sha256=' . hash_hmac(
    'sha256',
    $payload,
    $client_secret
);

if (!hash_equals($expected, $signature)) {
    http_response_code(403);
    exit('Invalid signature');
}

$event = json_decode($payload, true);
// Process the event...
```

> **Best practice:** Always verify the signature before processing webhook events. Return a `200` status code quickly to acknowledge receipt — do heavy processing asynchronously.
