Jupiter ERP

Webhooks

Jupiter ERP sendet fachliche Ereignisse per HTTPS POST an eine Adresse, die Sie hinterlegen. Diese Seite beschreibt die Nachricht, die Signatur und wann ein Ereignis entsteht.

POST · JSONAt-least-onceAPI 1.0.0Account API

Was ankommt

Methode
POST
Content-Type
application/json
Zeitlimit
10 Sekunden
Weiterleitungen
werden nicht verfolgt
User-Agent
Jupiter-ERP-Webhook/1.0
Signatur
Jupiter-ERP-Signature

Jupiter ERP ruft nur öffentliche HTTPS-Adressen auf. Ein fachliches Ereignis wird nur gespeichert, wenn mindestens ein aktiver Endpunkt den Typ abonniert hat. Dieselbe Ereigniskennung kann an mehrere Endpunkte gehen. Jeder Endpunkt hat seine eigene Zustellung.

webhook.ping startet nur über Test senden an genau diesem Endpunkt. Die Ereignisauswahl spielt dafür keine Rolle. Ein ausgeschalteter Endpunkt nimmt keinen Test an.

Endpunkte legen Sie im Panel unter System → Webhooks an. Die Funktion ist in der Testphase und im Enterprise-Paket enthalten, mit bis zu fünf Endpunkten. Eigene Header, zum Beispiel ein API-Schlüssel, sendet Jupiter ERP bei jeder Zustellung mit. Content-Type, User-Agent und Jupiter-ERP-Signature setzt Jupiter ERP selbst.

Signatur prüfen

Prüfen Sie jede Zustellung, bevor Sie den Inhalt annehmen. Signiert werden der Zeitstempel und der Rohtext des Bodys. Kein anderer Header geht in die Signatur ein.

  1. 1

    Rohtext lesen

    Lesen Sie den Body, bevor ein Framework ihn als JSON einliest. Der Text ist UTF-8. Die Signatur gilt für genau diese Bytes. Ein erneutes Formatieren ändert Leerzeichen, die Reihenfolge der Felder oder Schrägstriche, und dann passt die Signatur nicht mehr.

  2. 2

    Header zerlegen

    Der Header heißt Jupiter-ERP-Signature. Sein Wert hat die Form t=1710000000,v1=hex. Trennen Sie die Teile am Komma und jedes Teil am ersten Gleichheitszeichen. t ist Unix-Zeit in Sekunden. v1 ist die Signatur als Hex in Kleinbuchstaben.

  3. 3

    Zeitstempel prüfen

    Vergleichen Sie t mit Ihrer Uhr und lehnen Sie den Aufruf ab, wenn der Abstand größer als fünf Minuten ist. Das ist Ihre eigene Grenze. Jupiter ERP setzt keine. Jeder Zustellversuch setzt ein neues t und damit eine neue Signatur. Der Body bleibt gleich. Ob Sie den Vorgang schon verarbeitet haben, entscheiden Sie an der id, die mit evt_ beginnt.

  4. 4

    HMAC berechnen

    Der signierte Text ist t, direkt danach ein Punkt, direkt danach der Rohtext. Der Schlüssel ist das Signaturgeheimnis dieses Endpunkts. Das Verfahren ist HMAC-SHA256. Das Ergebnis ist Hex in Kleinbuchstaben.

  5. 5

    Vergleichen

    Vergleichen Sie v1 zeitkonstant mit dem berechneten Wert. In PHP ist das hash_equals, in Node timingSafeEqual, in Python hmac.compare_digest. Fehlt v1 oder weicht es ab, verwerfen Sie den Aufruf. Das Geheimnis sehen Sie nur beim Anlegen und beim Erneuern des Endpunkts.

Kontrollwerte

Mit diesen festen Bytes können Sie Ihre Prüfung vergleichen. Das Geheimnis ist ein Beispiel und gehört zu keinem Endpunkt.

Geheimnis
whsec_test_secret
t
1710000000
Rohtext
{"id":"evt_01EXAMPLE","type":"webhook.ping","api_version":"1.0.0","created_at":"2026-10-10T19:00:00+00:00","account_uuid":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","data":{"object":"ping","item":{"ok":true}}}
Signierter Text
1710000000.{"id":"evt_01EXAMPLE","type":"webhook.ping","api_version":"1.0.0","created_at":"2026-10-10T19:00:00+00:00","account_uuid":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","data":{"object":"ping","item":{"ok":true}}}
Header
t=1710000000,v1=951aa3172e030732bea285376242e0a047079aca0031abc2246f4539d0f74bba
Prüfung
import { createHmac, timingSafeEqual } from "node:crypto";

const MAX_SKEW_SECONDS = 5 * 60;

export function verifyJupiterSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((piece) => {
      const index = piece.indexOf("=");
      return [piece.slice(0, index), piece.slice(index + 1)];
    }),
  );
  const timestamp = Number(parts.t);
  if (!Number.isInteger(timestamp)) {
    return false;
  }
  if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > MAX_SKEW_SECONDS) {
    return false;
  }

  const expected = createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
  const actual = parts.v1 ?? "";
  if (expected.length !== actual.length) {
    return false;
  }
  return timingSafeEqual(Buffer.from(expected), Buffer.from(actual));
}

Antwort und Wiederholung

2xx

Die Zustellung ist erledigt. Antworten Sie innerhalb von 10 Sekunden und verarbeiten Sie danach.

410

Der Endpunkt wird sofort abgeschaltet. Das zählt nicht zu den zehn Fehlschlägen.

429, 5xx, Timeout, Netzwerk

Wiederholung nach etwa 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden, 8 Stunden und 12 Stunden. Die Abstände schwanken etwas. Nach dem siebten Versuch gilt die Zustellung als fehlgeschlagen.

Andere 4xx und Weiterleitung

Keine Wiederholung. Weiterleitungen werden nicht verfolgt.

Zehn Fehlschläge in Folge

Der Endpunkt wird abgeschaltet. Eine erfolgreiche Zustellung setzt den Zähler zurück.

Envelope

Wiederholungen senden denselben Body, aber einen neuen Zeitstempel in der Signatur. Beträge stehen in Cent: 11900 sind 119,00. account_uuid setzen Sie beim Nachladen als Header X-Account-Uuid an der Account API. Die id beginnt mit evt_. Dieselbe id ist derselbe Vorgang.

invoice.sent
{
  "id": "evt_01J7ABCDEFGHJKMNPQRSTVWXYZ",
  "type": "invoice.sent",
  "api_version": "1.0.0",
  "created_at": "2026-10-10T19:00:00+00:00",
  "account_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "object": "invoice",
    "item": {
      "id": 456,
      "status": "open",
      "number": 10001,
      "formatted_number": "RE-10001",
      "date": "2026-10-10",
      "sum_net": 10000,
      "sum_gross": 11900,
      "currency_code": "EUR",
      "contact": { "id": 12, "name": "Muster GmbH" },
      "project": null,
      "cost_center": null
    }
  }
}

Ereignisse

data.item ist eine Kurzfassung zum Zeitpunkt des Ereignisses. Den vollständigen Datensatz lesen Sie über die Account API.

Downloads

OpenAPI 3.1 beschreibt die Ereignisse unter webhooks. Es gibt keine paths: Jupiter ERP empfängt diese Aufrufe nicht.

Webhooks: Referenz · Jupiter ERP