Vorgio

Fehlerreferenz

Alle Non-2xx-Responses von /api/v1/* verwenden RFC 7807 application/problem+json:

 1HTTP/1.1 422 Unprocessable Entity
 2Content-Type: application/problem+json
 3
 4{
 5  "type": "https://accounting.example/problems/validation-failed",
 6  "title": "The given data was invalid.",
 7  "status": 422,
 8  "detail": "The invoice.positions.0.amount_cents field is required when invoice.positions.0.mode is fixed.",
 9  "errors": {
10    "invoice.positions.0.amount_cents": [
11      "The amount_cents field is required when mode is fixed."
12    ]
13  }
14}

Die type-URI ist stabil und ist das, worauf Ihr Code verzweigen sollte — niemals auf den title (der menschenlesbar ist und übersetzt sein kann).

#Häufige Problemtypen

#validation-failed (422)

Fehler in der Body-Form. Enthält ein errors-Objekt, das nach Feldpfad indiziert ist.

Was tun: dem Entwickler / Händler anzeigen; niemals dem Endkunden (die Feldpfade leaken das Schema). Die meisten Validierungsfehler bedeuten, dass Ihr Shop etwas geschickt hat, das Vorgio nicht akzeptiert — korrigieren Sie die Request-Form.

#idempotency-key-conflict (409)

Sie haben einen Idempotency-Key mit einem anderen Request-Body wiederverwendet. Vorgio lehnt ab, weil das einzig sichere Verhalten ist, den Konflikt sichtbar zu machen.

Was tun: wählen Sie einen anderen Idempotency-Key (oder schränken Sie den vorhandenen auf diesen Versuch ein — hängen Sie einen Retry-Counter an, z. B. wc-order-1234-checkout-r2). Modifizieren Sie nicht den Body und senden Sie ihn nicht unter demselben Key erneut.

#forbidden (403)

Der Token verfügt nicht über die Berechtigung, die der Endpoint erfordert. Zum Beispiel der Aufruf von POST /v1/checkouts mit einem Token, der nur clients:read hat.

Was tun: stellen Sie den Token mit den korrekten Abilities neu aus. Das Preset "Payment-provider integration" in der Token-UI wählt das richtige Set aus.

#unauthenticated (401)

Bearer-Token fehlt, ist fehlerhaft oder abgelaufen/widerrufen.

Was tun: prüfen Sie den Authorization-Header. Das Format ist Bearer {numeric_id}|{plain_secret} — beide Hälften durch einen Pipe getrennt. Senden Sie nicht nur die Secret-Hälfte.

#too-many-requests (429)

Rate Limit überschritten. Siehe Rate Limits.

#not-found (404)

Die Ressource existiert in Ihrem Team nicht. Beachten Sie, dass Ressourcen in anderen Teams ebenfalls 404 zurückgeben, nicht 403 — das ist Absicht (verhindert das Leaken der Existenz von Daten anderer Teams).

Was tun: prüfen Sie die client_id / invoice_id doppelt. Falls sie existieren sollte, prüfen Sie, ob sie soft-deleted wurde oder ob der Token zum falschen Team gehört.

#client-has-retained-invoices (409, bei DELETE /v1/clients/{id})

Sie haben versucht, einen Kunden zu löschen, dessen Rechnungen sich innerhalb der gesetzlichen 10-jährigen Aufbewahrungsfrist (HGB §257, AO §147) befinden. Vorgio lehnt dies aus rechtlichen Gründen ab.

Was tun: nicht löschen; stattdessen in Ihrem Shop archivieren.

#internal-error (5xx)

Etwas ist serverseitig explodiert. Das detail kann eine Fehlerreferenz für den Support enthalten.

Was tun: mit exponentiellem Back-off wiederholen; falls es weiterhin auftritt, senden Sie die Fehlerreferenz an den Vorgio-Support. Zeigen Sie die interne Fehlermeldung nicht Ihrem Endkunden an.

#Feldpfade bei Validierungsfehlern

Bei verschachtelten Request-Bodies (wie /v1/checkouts) verwenden Error-Keys Punkt-Notation:

Pfad Was er bedeutet
client.external_id Top-Level-Feld im client-Block
invoice.positions.0.amount_cents Das amount_cents-Feld der ersten Position
send.cc.2 Der dritte Eintrag im send.cc-Array

Wenn Sie Fehler an einen Entwickler zurückgeben, rendern Sie jeden Eintrag im errors-Array als Aufzählungspunkt unter dem zugehörigen Feldpfad.

#Empfohlenes Error-Handling-Muster (PHP)

 1try {
 2    $response = $http->post('/api/v1/checkouts', [...]);
 3} catch (RequestException $e) {
 4    $body = json_decode((string) $e->getResponse()->getBody(), true);
 5    $type = $body['type'] ?? '';
 6
 7    match (true) {
 8        str_ends_with($type, 'validation-failed') => $this->reportToDeveloper($body),
 9        str_ends_with($type, 'too-many-requests') => $this->scheduleRetry($body, $e->getResponse()->getHeader('Retry-After')[0] ?? 60),
10        str_ends_with($type, 'idempotency-key-conflict') => $this->logAndAlertEng($body),
11        $e->getCode() >= 500 => $this->retryWithBackoff(),
12        default => throw $e,
13    };
14}