# Webhooks

Webhooks allow you to receive real-time notifications when order or transaction statuses change — no need to poll the API.

<Callout type="tip" title="Recommended approach">
  Use webhooks as your primary method for tracking order statuses. API endpoints like `GET /orders/{id}/status` have strict [rate limits](/wiki/rate-limits) (15–25 req/min per order) and should only be used as a fallback.
</Callout>

## Setup

1. Go to the [**Partner Panel**](https://www.e-vignette.app) → Settings → Callback URLs
2. Add your Webhook URL for both `SANDBOX` and `PRODUCTION` environments

<Callout type="caution" title="Use separate URLs">
  Please use different URLs for `SANDBOX` and `PRODUCTION` environments to avoid mixing test and live data.
</Callout>

## How it works

- We send a `POST` request to your Webhook URL with a JSON body
- Your endpoint should respond with HTTP `200 OK` to confirm receipt
- If we don't receive a `200` response, we will retry the webhook up to **3 times** with increasing delays (1 min, 5 min, 15 min)

## Event types

| Event type | Description | When it fires |
|---|---|---|
| `CHECKOUT_STATUS_CHANGED` | Payment status update | Only if you use our payment system |
| `ORDER_STATUS_CHANGED` | Order status update | For all partners — on every status change |
| `ORDER_CONFIRMATION_RECEIVED` | PDF confirmation received | When the national provider sends the vignette confirmation file |

> **If you process payments yourself, skip the `Transactions` section and go to [Orders](#orders).**

---

## Transactions
(Only for partners using our payment system)

`"event_type": "CHECKOUT_STATUS_CHANGED"`

| Status | Description |
|---|---|
| `CREATED` | Payment URL has been created and provided to the partner |
| `SUCCESS` | User's payment has been successfully captured |
| `FAILED` | An error occurred during payment |

Example payload — single order:
```json
{
  "transaction_id": "3QM7irIto19ZALc12DWDGh53",
  "event_type": "CHECKOUT_STATUS_CHANGED",
  "status": "SUCCESS",
  "products": [
    {
      "custom_id": "partnerCustomID",
      "unique_id": "9x6tfz9cgo",
      "name": "vignette-si-2a"
    }
  ]
}
```

Example payload — multiple orders in one transaction:
```json
{
  "transaction_id": "3QM7irIto19ZALc12DWDGh53",
  "event_type": "CHECKOUT_STATUS_CHANGED",
  "status": "SUCCESS",
  "products": [
    {
      "custom_id": "partnerCustomID-1",
      "unique_id": "9x6tfz9cgo",
      "name": "vignette-si-2a"
    },
    {
      "custom_id": "partnerCustomID-2",
      "unique_id": "4x3tbz1iao",
      "name": "vignette-at-2a"
    }
  ]
}
```

---

## Orders
(For all partners)

### Order status changes

`"event_type": "ORDER_STATUS_CHANGED"`

| Status | Description |
|---|---|
| `CREATED` | Order is successfully paid and ready for registration with the national provider |
| `PENDING` | Order has started authorization with the national provider |
| `DEFERRED` | Order is scheduled for future activation |
| `ACTIVE` | Order is successfully registered — vignette is valid |
| `REFUNDED` | Order has been refunded (via cancel or chargeback) |

Example payload:
```json
{
  "event_type": "ORDER_STATUS_CHANGED",
  "status": "ACTIVE",
  "product": {
    "custom_id": "id-13bd396f3-8695-4e06-9db2-8002afead334",
    "unique_id": "8thrqjobhv",
    "name": "vignette-ch-2a"
  }
}
```

### Confirmation file received

`"event_type": "ORDER_CONFIRMATION_RECEIVED"`

This webhook is sent when we receive the official PDF confirmation from the national provider. The `pdf_url` field contains the direct link to the confirmation document.

Example payload:
```json
{
  "event_type": "ORDER_CONFIRMATION_RECEIVED",
  "status": "ACTIVE",
  "product": {
    "custom_id": "id-13bd396f3-8695-4e06-9db2-8002afead334",
    "unique_id": "8thrqjobhv",
    "name": "vignette-ch-2a",
    "pdf_url": "https://vignette.id/invoices/pdf/invoice.pdf"
  }
}
```

<Callout type="info" title="One webhook per order">
  If a transaction contains multiple orders, each order sends its own webhooks separately. One order webhook contains information about only one order.
</Callout>

---

## Complete webhook flow

A typical order lifecycle produces the following webhooks in sequence:

```
1. ORDER_STATUS_CHANGED → CREATED     ← order accepted, ready to process
          ↓
2. ORDER_STATUS_CHANGED → PENDING     ← processing with national provider
                          or DEFERRED ← scheduled for future activation
          ↓
3. ORDER_STATUS_CHANGED → ACTIVE      ← vignette is now valid
          ↓
4. ORDER_CONFIRMATION_RECEIVED        ← PDF confirmation from provider
   (includes pdf_url)
```

<Callout type="tip" title="When to show confirmation to user">
  After receiving `ORDER_STATUS_CHANGED → ACTIVE`, the vignette is already valid and the user can drive. The `ORDER_CONFIRMATION_RECEIVED` webhook with `pdf_url` may arrive a few seconds to minutes later — use it to provide the official confirmation document to the user.
</Callout>

For more details on all available statuses, see [Statuses list](/wiki/statuses).
