Dokumentation / Integration

Webhooks

Coinetic meldet Ihrem Server Änderungen an einer Rechnung per POST-Anfrage. Ein Webhook ist ein Signal „Rechnung prüfen“, kein Zahlungsnachweis.

Einrichtung

  • Dashboard → „Schlüssel und Webhooks“ → „Hinzufügen“. Die URL muss https:// auf eine öffentliche Adresse und Port 443 sein (in der Sandbox zusätzlich http://localhost).
  • Das Endpoint-Secret wird einmal angezeigt. Bis zu 5 aktive Endpoints: Jedes Ereignis geht an alle.

Anfrage

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 bleibt bei Wiederholungen gleich. Während einer Secret-Rotation enthält X-Webhook-Signature zwei Signaturen, durch Komma getrennt. Technische Namen (cryptopay-webhooks/1) sind historisch bedingt – Sie müssen bei sich nichts ändern.

Signatur prüfen

text
expected = "v1=" + hex(HMAC-SHA256(webhook_secret, X-Webhook-Timestamp + "." + raw_body))
  1. Nehmen Sie den rohen Body – die Bytes vor dem JSON-Parsing.
  2. Prüfen Sie, dass X-Webhook-Timestamp höchstens 5 Minuten von der aktuellen Zeit abweicht.
  3. Teilen Sie X-Webhook-Signature am Komma. Die Signatur ist gültig, wenn irgendein Teil mit dem erwarteten Wert übereinstimmt (Vergleich in konstanter Zeit).
  4. Keine Übereinstimmung – antworten Sie mit 401 und tun Sie nichts weiter.

Referenz: Secret whsec-0123456789abcdef0123456789abcdef, Timestamp 1760000000, Body {"id":"evt_1","type":"invoice.paid"} → v1=aceeb56215ba09e7a2923d48f89afb8331f422f2d0a8cf60f76fef69fe06a6a4.

Verarbeitung

text
Signatur prüfen → Deduplizierung über X-Webhook-Id → GET /v1/invoices/{invoice_id}
→ Bestellung nach Status aus der API aktualisieren (genau einmal ausliefern) → mit 2xx antworten
  • Deduplizierung. Ein Ereignis kann mehrfach eintreffen. Speichern Sie verarbeitete X-Webhook-Id; setzen Sie das Flag „ausgeliefert“ in derselben Transaktion wie die Auslieferung.
  • Antworten Sie schnell – innerhalb von 10 Sekunden. Längere Arbeit gehört in eine Queue.
  • Antwortcodes: 2xx – angenommen; 410 Gone – diese Zustellung nicht wiederholen; jeder andere Code (auch 3xx – Redirects werden nicht verfolgt) oder ein Timeout – Wiederholung.
  • Ignorieren Sie unbekannte Felder und Ereignistypen – die Liste wird wachsen.

Fertige Handler in vier Sprachen finden Sie im Schnellstart.

Wiederholungen

10 s → 30 s → 2 Min. → 10 Min. → 30 Min. → 1 h → 3 h ×7 → 1 h, mit leichter Streuung. Der letzte Versuch erfolgt nach etwa 24 Stunden. Eine fehlgeschlagene Zustellung können Sie erneut senden: Dashboard → „Webhooks“ → „Erneut senden“.

Reihenfolge

Ereignisse einer Rechnung werden in Reihenfolge an einen Endpoint zugestellt: Das nächste geht erst raus, wenn die vorherige Zustellung nicht mehr auf eine Wiederholung wartet. Ob sie erfolgreich war oder nicht – danach folgen die nächsten. Verlassen Sie sich deshalb auf den Status aus GET /v1/invoices/{id}, nicht auf die Reihenfolge der Ereignisse. Ereignisse verschiedener Rechnungen sind unabhängig.

Ereignistypen

EreignisWann
invoice.detectedZahlung im Netzwerk sichtbar
invoice.confirmingZahlung im Block, Bestätigungen laufen
invoice.paidBezahlt und bestätigt – Auslieferung möglich (nach Gegenprüfung). data.late: true – Stablecoin kam nach Ablauf und wurde automatisch gutgeschrieben
invoice.overpaidMit Überschuss bezahlt
invoice.underpaidWeniger als nötig bestätigt
invoice.awaiting_paymentRechnung wartet erneut auf Zahlung (z. B. nach dem Reorg der einzigen Zahlung)
invoice.expiredAbgelaufen ohne Zahlung
invoice.late_paymentZahlung in einem volatilen Asset nach Ablauf
invoice.manual_reviewZahlung in der AML-Prüfung
invoice.payment_heldZahlung durch AML zurückgehalten (Quarantäne)
invoice.reorgedBlock mit der Zahlung wurde zurückgerollt, Status neu berechnet (z. B. paid → confirming)
invoice.payment_after_closeZahlung auf eine bereits geschlossene Rechnung: bezahlt die Bestellung nicht, kann erstattet werden
invoice.cancelledRechnung ohne Zahlung durch Ausführung einer Erstattung geschlossen
refund.sentErstattung ausgeführt, data.refund enthält Betrag, Adresse und tx_hash

Abrechnungsereignisse (billing.*) betreffen die Gebührenrechnungen der Plattform: gestellt, bezahlt, überfällig, Sperre und deren Aufhebung.

Digitale Güter und invoice.reorgedEin Reorg nach paid ist selten, kommt aber vor. Wenn Sie Ware sofort ausliefern, abonnieren Sie dieses Ereignis und geben Sie solche Fälle an den Support weiter.

Secret-Rotation

Dashboard → „Secret ändern“: Coinetic signiert ab dann mit beiden Secrets.

  1. Hinterlegen Sie das neue Secret auf dem Server (akzeptieren Sie beide).
  2. Klicken Sie auf „Rotation abschließen“ – das alte wird gelöscht.
  3. Entfernen Sie das alte Secret vom Server.