---
title: Webhooks
description: Webhooks van Coinetic: instellen, de HMAC-handtekening verifiëren, deduplicatie, retries, volgorde van levering, eventtypes en rotatie van het secret.
url: https://coinetic.money/nl/docs/webhooks/
lang: nl
---

# Webhooks

Coinetic meldt wijzigingen in een factuur met een POST-request aan uw server. Een webhook is een signaal ‘bekijk de factuur’, geen bewijs van betaling.

## Instellen

- Dashboard → ‘Sleutels en webhooks’ → ‘Toevoegen’. De URL is alleen `https://` naar een publiek adres op poort 443 (in de sandbox ook `http://localhost`).
- Het secret van het endpoint wordt één keer getoond. Maximaal 5 actieve endpoints: elk event gaat naar allemaal.

## Request

```http
POST /webhooks/coinetic HTTP/1.1
Content-Type: application/json
User-Agent: cryptopay-webhooks/1
X-Webhook-Id: evt_3f9c…
X-Webhook-Timestamp: 1760000000
X-Webhook-Signature: v1=5d1e…

{"id":"evt_3f9c…","type":"invoice.paid","created_at":"2026-10-12T15:04:05Z","livemode":true,"data":{"invoice_id":"inv_x7k2…","order_id":"ORDER-1001","status":"paid","paid_amount":"49990000"}}
```

`X-Webhook-Id` blijft gelijk bij retries. Tijdens de rotatie van een secret staan er in `X-Webhook-Signature` twee handtekeningen, gescheiden door een komma. De technische namen (`cryptopay-webhooks/1`) zijn historisch; u hoeft ze aan uw kant niet aan te passen.

## De handtekening verifiëren

```
expected = "v1=" + hex(HMAC-SHA256(webhook_secret, X-Webhook-Timestamp + "." + raw_body))
```

- Neem de **ruwe body** — de bytes vóór het parsen van de JSON.
- Controleer dat `X-Webhook-Timestamp` niet meer dan 5 minuten afwijkt van de huidige tijd.
- Splits `X-Webhook-Signature` op de komma. De handtekening is geldig als **een willekeurig** deel overeenkomt met de verwachte waarde (vergelijken in constante tijd).
- Geen overeenkomst — antwoord met `401` en doe verder niets.

Referentie: secret `whsec-0123456789abcdef0123456789abcdef`, timestamp `1760000000`, body `{"id":"evt_1","type":"invoice.paid"}` → `v1=aceeb56215ba09e7a2923d48f89afb8331f422f2d0a8cf60f76fef69fe06a6a4`.

## Verwerking

```
handtekening verifiëren → dedupliceren op X-Webhook-Id → GET /v1/invoices/{invoice_id}
→ order bijwerken op basis van de status uit de API (precies één keer leveren) → antwoorden met 2xx
```

- **Deduplicatie.** Hetzelfde event kan meerdere keren binnenkomen. Sla verwerkte `X-Webhook-Id`'s op; zet de vlag ‘geleverd’ in dezelfde transactie als de levering zelf.
- **Antwoord snel** — binnen 10 seconden. Zet langdurig werk in een queue.
- **Responscodes:** `2xx` — geaccepteerd; `410 Gone` — deze levering niet opnieuw proberen; elke andere code (ook `3xx` — redirects worden niet gevolgd) of een timeout — retry.
- Negeer onbekende velden en eventtypes — de lijst wordt nog uitgebreid.

Kant-en-klare handlers in vier talen vindt u in de [snelstart](https://coinetic.money/nl/docs/quickstart/#webhook).

## Retries

10 s → 30 s → 2 min → 10 min → 30 min → 1 u → 3 u ×7 → 1 u, met een kleine spreiding. De laatste poging volgt na ongeveer een etmaal. Een mislukte levering kunt u opnieuw versturen: dashboard → ‘Webhooks’ → ‘Opnieuw verzenden’.

## Volgorde

Events van **één factuur** worden in volgorde aan het endpoint geleverd: het volgende gaat pas weg als de vorige levering niet meer op een retry wacht. Of die levering nu is geslaagd of niet — daarna gaan de volgende events. Baseer u daarom op de status uit `GET /v1/invoices/{id}`, niet op de volgorde van de events. Events van verschillende facturen zijn onafhankelijk van elkaar.

## Eventtypes

| Event | Wanneer |
| --- | --- |
| `invoice.detected` | De betaling is zichtbaar in het netwerk |
| `invoice.confirming` | De betaling staat in een blok, de bevestigingen lopen |
| `invoice.paid` | Betaald en bevestigd — u kunt leveren (na een extra controle). `data.late: true` — de stablecoin kwam na de vervaldatum binnen en is automatisch verrekend |
| `invoice.overpaid` | Betaald met een overschot |
| `invoice.underpaid` | Minder bevestigd dan nodig |
| `invoice.awaiting_payment` | De factuur wacht weer op betaling (bijvoorbeeld na een reorg van de enige betaling) |
| `invoice.expired` | De looptijd is verstreken zonder betaling |
| `invoice.late_payment` | Betaling in een volatiele asset na de vervaldatum |
| `invoice.manual_review` | De betaling wordt gecontroleerd op AML |
| `invoice.payment_held` | De betaling is door AML vastgehouden (quarantaine) |
| `invoice.reorged` | Het blok met de betaling is teruggedraaid, de status is herberekend (bijvoorbeeld `paid` → `confirming`) |
| `invoice.payment_after_close` | Een betaling op een al gesloten factuur: die betaalt de order niet, maar kan worden terugbetaald |
| `invoice.cancelled` | De factuur is zonder betaling gesloten door het uitvoeren van een terugbetaling |
| `refund.sent` | De terugbetaling is uitgevoerd; in `data.refund` staan het bedrag, het adres en de `tx_hash` |

Facturerings-events (`billing.*`) gaan over de facturen voor de platformcommissie: uitgegeven, betaald, achterstallig, opschorting en het opheffen daarvan.

> **Digitale producten en `invoice.reorged`.** Een reorg na `paid` is zeldzaam, maar komt voor. Levert u het product direct, abonneer u dan op dit event en geef zulke gevallen door aan uw support.

## Rotatie van het secret

Dashboard → ‘Secret wijzigen’: Coinetic ondertekent vanaf dan met **beide** secrets.

- Zet het nieuwe secret op uw server (accepteer beide).
- Klik op ‘Rotatie voltooien’ — het oude wordt verwijderd.
- Verwijder het oude secret van uw server.
