{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "Kevmi — Server-API",
    "version": "2026-10-23.12",
    "description": "Kevmi-API: Telegram-Anmeldung, Sitzungen, Händlerrechnungen, verschlüsselter Käufer-Checkout, Support, Benachrichtigungen, Anwendungen und Webhook-Zustellung. Nur einmalige direkte Zahlungen. JSON-Antworten verwenden no-store. Zeitstempel sind UTC-Unix-Millisekunden, sofern nicht anders angegeben. Der Live-Checkout verwendet ein konfiguriertes externes Gateway; Karten- und Bankcodefelder werden im Browser verschlüsselt und nur vom Gateway entschlüsselt. Neue Belastungen erfordern die Genehmigung der neuesten Händler-Website-Anwendung. Das Erstellen einer Rechnung belastet keinen Käufer.",
    "x-updated-at": "2026-10-23"
  },
  "servers": [
    {
      "url": "https://kevmi.one",
      "description": "Der öffentliche Projektursprung; die Hosting-Plattform kann zusätzliche Zugriffskontrollen anwenden."
    }
  ],
  "externalDocs": {
    "description": "Öffentliche Produktdokumentation",
    "url": "https://kevmi.one/docs"
  },
  "tags": [
    {
      "name": "Service",
      "description": "Öffentlicher Servicestatus."
    },
    {
      "name": "Auth",
      "description": "Registrierung und Anmeldung teilen sich den verifizierten Telegram-Ablauf."
    },
    {
      "name": "Account",
      "description": "Einstellungen nur für den aktuellen Benutzer."
    },
    {
      "name": "Payment links",
      "description": "Serverrechnungen für den aktuellen Shop. Preis, Währung, MwSt-Zahler, Verkäufername und Berechnung sind unveränderlich."
    },
    {
      "name": "Checkout",
      "description": "Eine Rechnung ohne Konto lesen. Die Zahlungsverfügbarkeit wird separat geprüft."
    },
    {
      "name": "Support",
      "description": "Öffentliche Wissensdatenbank und Support-Anfragen des aktuellen Benutzers."
    },
    {
      "name": "Notifications",
      "description": "Konto-Ereigniszentrum, Website-Lesestatus und unabhängiger Telegram-Zustellstatus."
    },
    {
      "name": "Telegram",
      "description": "Bot-Webhook; kein Zahlungs-Webhook."
    },
    {
      "name": "Disabled payments",
      "description": "Nicht unterstützte Alt-Geldwege und Auszahlungsausführung. Der öffentliche Checkout-Ablauf hat eigene dokumentierte Endpunkte."
    },
    {
      "name": "Merchant API",
      "description": "Bereichsbezogene Server-zu-Server-Rechnungen und unveränderlicher Ereignisverlauf."
    },
    {
      "name": "Webhooks",
      "description": "Verifizierte HTTPS-Endpunkte, signierte Ereignisse, Zustellversuche und Wiederholungen."
    },
    {
      "name": "Applications",
      "description": "Authentifizierte Website-Anwendungen und individuelle Nachverfolgung."
    },
    {
      "name": "Moderation",
      "description": "Zugelassene Telegram-Moderatoren; jede Entscheidung wird versionsgeprüft."
    },
    {
      "name": "Gateway events",
      "description": "Quellnative Gateway-Ereignisse werden verifiziert, dann wird die maßgebliche Zahlung über authentifizierten Server-Transport gelesen. Händlerbezogene Webhooks verwenden eine separate Signatur und Zustellwarteschlange."
    }
  ],
  "security": [],
  "x-disabled-route-prefixes": [
    "/api/payments",
    "/api/payouts",
    "/api/gateway",
    "/api/linzapay"
  ],
  "x-disabled-route-behavior": "Legacy unscoped direct-money routes and payout execution remain disabled. Authenticated /api/v1/payments creates invoices; /api/checkout/{token} exposes the separate buyer checkout flow. POST /api/gateway/webhook accepts signed gateway events.",
  "paths": {
    "/api/config": {
      "get": {
        "tags": [
          "Service"
        ],
        "operationId": "getConfig",
        "summary": "Aktuelle Integrationsbereitschaft",
        "responses": {
          "200": {
            "description": "Konfiguration ohne Geheimnisse.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Config"
                }
              }
            }
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": [
          "Service"
        ],
        "operationId": "getHealth",
        "summary": "API- und D1-Tabellenstatus",
        "description": "not_configured kann status=ok haben: Öffentliche Seiten und Suche können ohne Datenbank ausgeführt werden. Eine konfigurierte Datenbank mit nicht verfügbaren Tabellen gibt 503/degraded zurück. Diese Antwort testet keine Telegram- oder Modell-Netzwerkkonnektivität.",
        "responses": {
          "200": {
            "description": "Speicherung ist bereit oder not_configured.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "503": {
            "description": "D1 ist nicht verfügbar oder ein unerwarteter Dienstfehler ist aufgetreten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Health"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/me": {
      "get": {
        "tags": [
          "Auth"
        ],
        "operationId": "getCurrentSession",
        "summary": "Aktuelle Sitzung und CSRF",
        "security": [
          {},
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "authenticated=false, wenn keine gültige Sitzung vorhanden ist.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Anonymous"
                    },
                    {
                      "$ref": "#/components/schemas/CurrentSession"
                    }
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/auth/telegram/start": {
      "post": {
        "tags": [
          "Auth"
        ],
        "operationId": "startTelegramLogin",
        "summary": "Anmeldung oder Registrierung starten",
        "description": "Erstellt eine 300-Sekunden-Herausforderung und ein HttpOnly-Browser-Nachweiscookie; maximal sechs Starts pro Minute pro gehaschter Adresse. Vergleichen Sie den sechsstelligen Code auf der Website und im privaten Bot-Chat.",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Anmeldungsanfrage erstellt; das Nachweiscookie bindet sie an den ursprünglichen Browser.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "Secure; HttpOnly; SameSite=Lax; Path=/. JavaScript kann nicht auf den Sitzungswert zugreifen. Der Abschluss der Anmeldung löscht auch das Browser-Nachweiscookie."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginChallenge"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/auth/telegram/complete": {
      "post": {
        "tags": [
          "Auth"
        ],
        "operationId": "completeTelegramLogin",
        "summary": "Eine verifizierte Anmeldung abschließen",
        "description": "Erfordert das Nachweiscookie vom Start und denselben Browser. Ausstehend gibt 202 zurück. Nach der Bot-Bestätigung stellt die Anfrage eine 24-Stunden-Sitzung aus. Bis zu 90 Prüfungen pro Minute pro Herausforderung. Eine vom Client gelieferte Telegram-ID wird nicht akzeptiert.",
        "security": [
          {
            "browserProof": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "challengeId": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9_-]{43}$"
                  }
                },
                "required": [
                  "challengeId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Konto erstellt oder aktualisiert und Sitzung ausgestellt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "Secure; HttpOnly; SameSite=Lax; Path=/. JavaScript kann nicht auf den Sitzungswert zugreifen. Der Abschluss der Anmeldung löscht auch das Browser-Nachweiscookie."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompletedLogin"
                }
              }
            }
          },
          "202": {
            "description": "Wartet auf Bestätigung in Telegram.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "pending"
                    }
                  },
                  "required": [
                    "status"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "410": {
            "description": "Die Fünf-Minuten-Anmeldungsanfrage ist abgelaufen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_EXPIRED"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/auth/logout": {
      "post": {
        "tags": [
          "Auth"
        ],
        "operationId": "logoutCurrentSession",
        "summary": "Aktuelle Sitzung beenden",
        "description": "Kein Body ist erforderlich oder wird gelesen. Der /logout-Befehl des Bots beendet separat alle Kontositzungen.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sitzung entfernt und Cookie gelöscht.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "Secure; HttpOnly; SameSite=Lax; Path=/. JavaScript kann nicht auf den Sitzungswert zugreifen. Der Abschluss der Anmeldung löscht auch das Browser-Nachweiscookie."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "loggedOut": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "loggedOut"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/account/settings": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccountSettings",
        "summary": "Aktuelle Benutzereinstellungen",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Öffentliche Felder des Profils des aktuellen Benutzers.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ]
      },
      "patch": {
        "tags": [
          "Account"
        ],
        "operationId": "updateAccountSettings",
        "summary": "Shopname, MwSt-Zahler oder Benachrichtigungen ändern",
        "description": "Alle Felder sind optional: Teilweises Patch. Das Speichern von vatPayer erstellt keine finanzielle Transaktion. Die Schalter für Zahlungen und Auszahlungen steuern Präferenzen, nicht die Gateway-Verfügbarkeit.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SettingsPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profil aktualisiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/support/ask": {
      "post": {
        "tags": [
          "Support"
        ],
        "operationId": "askDocumentation",
        "summary": "Antwort aus der vollständigen öffentlichen Wissensdatenbank",
        "description": "Öffentliche Frage ohne Sitzung oder CSRF. Eine gelieferte Origin muss APP_ORIGIN entsprechen; Agenten können sie weglassen. Im KI-Modus sendet der Server alle veröffentlichten Artikel, Fakten, Seitenkatalog und Funktionsbereitschaft. Optionale history und pageContext sind nicht vertrauenswürdige Fragekontexte. Das Modell kann nicht auf Konten, Geld, private Anfragen oder Werkzeuge zugreifen. Mit D1 liegt das Limit bei 12 Fragen pro Minute pro gehashter Adresse. KI erfordert D1, gültige Anbieterkonfiguration und Kontingent: 60 Generierungen pro Stunde dienstweit standardmäßig. Konfigurationsbereitschaft beweist keine externe API-Verfügbarkeit. Anbieterfehler, Kontingenterschöpfung oder ungültige Ausgabe liefern Suche mit aiUnavailable=true und HTTP 200. Ohne Generierungskonfiguration wird reguläre Suche zurückgegeben.",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": false,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt bis zu 65.536 Bytes. Unbekannte Felder werden abgelehnt. Textlängen werden nach dem Trimmen geprüft.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SupportQuestion"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Eine Antwort oder passende Dokumentation mit validierten Artikellinks.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupportAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/support/tickets": {
      "get": {
        "tags": [
          "Support"
        ],
        "operationId": "listOwnTickets",
        "summary": "Die neuesten 30 eigene Support-Anfragen",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Neueste zuerst nach createdAt; gibt die neuesten 30 Datensätze zurück.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tickets": {
                      "type": "array",
                      "maxItems": 30,
                      "items": {
                        "$ref": "#/components/schemas/Ticket"
                      }
                    }
                  },
                  "required": [
                    "tickets"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      },
      "post": {
        "tags": [
          "Support"
        ],
        "operationId": "createOwnTicket",
        "summary": "Eine Support-Anfrage speichern",
        "description": "Bis zu sechs Anfragen pro Benutzer pro Stunde, gemeinsam von Website und Bot genutzt. Das Speichern erstellt einen Kontodatensatz. Behalten Sie dessen Referenz, um nach dem Status zu fragen.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "minLength": 1,
                    "x-trimmedMaxLength": 120,
                    "x-trimmedMinLength": 1,
                    "description": "Umgebende Leerzeichen werden getrimmt. Länge nach dem Trimmen: 1–120 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
                  },
                  "message": {
                    "type": "string",
                    "minLength": 5,
                    "x-trimmedMaxLength": 4000,
                    "x-trimmedMinLength": 5,
                    "description": "Umgebende Leerzeichen werden getrimmt. Länge nach dem Trimmen: 5–4.000 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
                  }
                },
                "required": [
                  "subject",
                  "message"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Support-Anfrage gespeichert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TicketResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/support/tickets/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^tkt_[a-f0-9-]{36}$"
          },
          "description": "Kennung einer eigenen Support-Anfrage."
        }
      ],
      "get": {
        "tags": [
          "Support"
        ],
        "operationId": "getOwnTicket",
        "summary": "Eine eigene Support-Anfrage lesen",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Die Anfrage eines anderen Benutzers und eine fehlende Anfrage geben beide 404 zurück.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TicketResponse"
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      },
      "patch": {
        "tags": [
          "Support"
        ],
        "operationId": "closeOwnTicket",
        "summary": "Eine eigene Support-Anfrage schließen",
        "description": "Die einzige erlaubte Änderung ist status=closed. Diese API öffnet Anfragen nicht erneut, bearbeitet keine Nachrichten und übermittelt keine Betreiberantworten.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "const": "closed"
                  }
                },
                "required": [
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Support-Anfrage geschlossen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "closed": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "closed"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/notifications": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "operationId": "listOwnNotifications",
        "summary": "Eine Seite eigener Benachrichtigungen",
        "description": "Bis zu 30 Datensätze, sortiert nach createdAt DESC und dann id DESC. Auflisten ändert readAt nicht und löst keine Zustellung aus. unreadCount ist die Gesamtzahl ungelesener Benachrichtigungen des aktuellen Benutzers über alle Seiten. Besitzerfelder, Telegram-ID und Geheimnisse sind ausgeschlossen.",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "parameters": [
          {
            "name": "unread",
            "in": "query",
            "description": "1 wählt nur ungelesene aus; 0 oder ein weggelassener Wert wählt alle Ereignisse aus.",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1"
              ],
              "default": "0"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "nextCursor aus der vorherigen Antwort. Unverändert über URLSearchParams übergeben; Format createdAt:id, wobei createdAt eine sichere Ganzzahl in Millisekunden ist.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{1,16}:ntf_[A-Za-z0-9-]{1,80}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ereignisse mit unabhängigen Lese- und Zustellungszuständen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationsPage"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/notifications/read": {
      "patch": {
        "tags": [
          "Notifications"
        ],
        "operationId": "markOwnNotificationsRead",
        "summary": "Eigene Benachrichtigungen als gelesen markieren",
        "description": "Akzeptiert entweder ids oder all:true zusammen mit before. before ist die Zeit des letzten beobachteten Ereignisses und darf die Serverzeit nicht überschreiten. Neuere Ereignisse bleiben ungelesen. Die Anfrage ist idempotent: vorhandene readAt-Werte ändern sich nicht. IDs anderer Benutzer und fehlende IDs werden weder geändert noch offengelegt. Telegram-Status und sentAt bleiben unverändert.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReadNotifications"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Die Anzahl neu gelesener Ereignisse, Betriebszeit und aktuelle ungelesene Anzahl.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadNotificationsResult"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/notifications/test": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "operationId": "testOwnNotification",
        "summary": "Eine Test-Benachrichtigung an das Telegram des Kontos senden",
        "description": "Stellt eine Nachricht in die Warteschlange und versucht die Zustellung. Höchstens drei pro Benutzer pro Stunde. Der Test ist keine Zahlungsbenachrichtigung und ändert keinen Saldo. HTTP 202 bestätigt keine Zustellung; prüfen Sie die Benachrichtigungsliste.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Warteschlangenergebnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "queued"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/telegram/webhook": {
      "post": {
        "tags": [
          "Telegram"
        ],
        "operationId": "receiveTelegramUpdate",
        "summary": "Ein Telegram-Bot-API-Ereignis empfangen",
        "description": "Erfordert nur den Telegram-Geheimnis-Header, ohne Sitzung, CSRF oder Origin. Zusätzliche Update-Felder sind erlaubt. Behandelt message und callback_query; persönliche Aktionen erfordern den verifizierten privaten Chat des Absenders. Andere Updates werden übersprungen. update_id wird dedupliziert; ein laufendes Update gibt 503 für Wiederholung zurück. Dies ist kein Webhook eines Zahlungsanbieters.",
        "security": [
          {
            "telegramWebhookSecret": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Telegram-Update, maximal 65.536 Bytes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TelegramUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verarbeitet, übersprungen oder bereits behandelt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "ok"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Telegram-Anfrage fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TELEGRAM_UNAVAILABLE",
              "TELEGRAM_INVALID_RESPONSE",
              "TELEGRAM_RATE_LIMITED",
              "TELEGRAM_DELIVERY_FAILED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/payments": {
      "post": {
        "tags": [
          "Disabled payments"
        ],
        "operationId": "paymentsUnavailable",
        "summary": "Finanzoperation nicht verfügbar",
        "description": "Gibt 503 GATEWAY_NOT_CONNECTED zurück. Finanzoperationen sind nicht verfügbar. Der Text wird nicht verarbeitet und keine Gateway-Anfrage wird gestellt.",
        "security": [],
        "responses": {
          "503": {
            "description": "Finanzoperationen sind nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "const": "GATEWAY_NOT_CONNECTED"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/api/payouts": {
      "post": {
        "tags": [
          "Disabled payments"
        ],
        "operationId": "payoutsUnavailable",
        "summary": "Finanzoperation nicht verfügbar",
        "description": "Gibt 503 GATEWAY_NOT_CONNECTED zurück. Finanzoperationen sind nicht verfügbar. Der Text wird nicht verarbeitet und keine Gateway-Anfrage wird gestellt.",
        "security": [],
        "responses": {
          "503": {
            "description": "Finanzoperationen sind nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "const": "GATEWAY_NOT_CONNECTED"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "Service"
        ],
        "operationId": "getOpenApi",
        "summary": "Öffentlicher maschinenlesbarer Vertrag",
        "description": "Nur Lesen. Enthält keine Geheimnisse, Sitzungen, Benutzerdatensätze oder betrieblichen Zahlungsanbieter-Vertrag.",
        "responses": {
          "200": {
            "description": "Dieses OpenAPI-3.1-Dokument.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "public, max-age=300"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "openapi",
                    "info",
                    "paths"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/payment-links": {
      "get": {
        "tags": [
          "Payment links"
        ],
        "operationId": "listOwnPaymentLinks",
        "summary": "Eigene Zahlungslinks auflisten",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "description": "Sortiert nach createdAt DESC, id DESC. Öffentliche Links funktionieren geräteübergreifend; Auflisten erfordert ein Konto.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "nextCursor aus der vorherigen Antwort. Der Dienst verwendet base64-JSON [createdAt,id]; übergeben Sie es unverändert über URLSearchParams."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "responses": {
          "200": {
            "description": "Eine Seite eigener Zahlungslinks.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinksPage"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      },
      "post": {
        "tags": [
          "Payment links"
        ],
        "operationId": "createOwnPaymentLink",
        "summary": "Eine Rechnung mit unveränderlichen Bedingungen erstellen",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,100}$"
            },
            "description": "Ein Schlüssel pro logischer Anfrage. Eine Wiederholung mit identischer kanonischer Eingabe gibt den ursprünglichen Datensatz zurück; andere Eingabe mit demselben Schlüssel gibt 409 zurück."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "description": "Eine unveränderliche Rechnung erstellen und sofort checkoutUrl erhalten; dies belastet den Käufer nicht. USD: Karte/Alipay; RUB: SBP; USDT: Krypto. USD-Krypto bleibt aus Kompatibilitätsgründen akzeptiert, kann aber ohne USDT-Rechnung nicht bezahlt werden. Gebühren- und Mehrwertsteuer-Kundenanteile sind unabhängige Ganzzahlen von 0 bis 100; aktuelle Live-Karte/Alipay unterstützt Mehrwertsteuer-Kunde=100 und Gebühren-Kunde=0. Die Kundensumme wird nie stillschweigend geändert. Neueste Website-Anwendung muss vor einer neuen Live-Belastung genehmigt werden. Rechnungserstellung und ihr Händlerereignis committen atomar.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotente Wiederholung; replayed=true.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePaymentLinkResponse"
                }
              }
            }
          },
          "201": {
            "description": "Rechnung erstellt; replayed=false.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePaymentLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/payment-links/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^lnk_[0-9a-f-]{36}$"
          },
          "description": "Kennung des eigenen Links, nicht das öffentliche Token."
        }
      ],
      "get": {
        "tags": [
          "Payment links"
        ],
        "operationId": "getOwnPaymentLink",
        "summary": "Eigener Link und gespeicherte Berechnung",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Die ID eines anderen Benutzers und eine fehlende ID geben beide 404 zurück.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ]
      },
      "patch": {
        "tags": [
          "Payment links"
        ],
        "operationId": "changePaymentLinkStatus",
        "summary": "Einen Link pausieren, fortsetzen oder abbrechen",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "description": "Ändert nur status. Das Update und das unveränderliche Rechnungs-updated-Ereignis committen atomar. Gleichzeitige Änderungen verwenden eine Versionsprüfung; bei LINK_CHANGED aktualisieren und erneut versuchen. cancelled ist endgültig, Ablauf wird nie verlängert, und Preis, Methoden, Kostenanteile und Beschreibung bleiben eingefroren. Das Wiederholen des gespeicherten Status gibt die aktuelle Rechnung zurück.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused",
                      "cancelled"
                    ]
                  }
                },
                "required": [
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Aktueller Zustand des eigenen Links.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "get": {
        "tags": [
          "Checkout"
        ],
        "operationId": "getPublicCheckout",
        "summary": "Öffentliche Rechnungsdetails für den Kunden",
        "description": "Lesen Sie das unveränderliche öffentliche Rechnungsangebot und dessen gespeicherten Zahlungs-Snapshot. method muss zur Rechnung gehören. Kein Konto ist erforderlich. Gibt keine Besitzeridentität, private Metadaten oder Händlererlöse preis. Das Token gewährt Zugriff nur auf diesen Checkout. availability spiegelt Konfiguration, Zuteilung, technische Grenzen und Händlergenehmigung wider; Zahlungsbestätigung ist getrennt.",
        "parameters": [
          {
            "name": "method",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "card",
                "alipay",
                "sbp",
                "crypto"
              ]
            },
            "description": "Muss in den gespeicherten Methoden der Rechnung vorhanden sein."
          }
        ],
        "responses": {
          "200": {
            "description": "Öffentliche Rechnung und die vorhandene Zahlung, falls ausgelöst.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoice": {
                      "$ref": "#/components/schemas/CheckoutInvoice"
                    },
                    "payment": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/CheckoutPayment"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "invoice",
                    "payment"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}/pay": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "post": {
        "tags": [
          "Checkout"
        ],
        "operationId": "startCheckoutPayment",
        "summary": "Die Rechnungszahlung starten oder wiederherstellen",
        "description": "Gleichherkunft-Käufer-Operation; kein Konto oder CSRF-Token erforderlich. Der Server reserviert eine Operation und einen stabilen Idempotenz-Schlüssel vor dem Gateway-Versand. Eine Wiederholung stellt dieselbe Operation wieder her; eine verlorene Antwort muss über den Status geklärt werden. Die Zahlungsmethode wird nach dem Versand gesperrt. Kartendaten müssen im Browser mit einem frischen Zahlungs-Intent verschlüsselt werden. SBP/Krypto senden die gespeicherte Kundensumme; Karte/Alipay verwenden die unterstützte unveränderliche Steuerkonfiguration. Neue Belastungen erfordern einen genehmigten Händlerantrag. Bereits versandte Zahlungen können nach Ablauf der Rechnung, Pause oder Genehmigungsänderungen wiederhergestellt werden. Keine /v2- oder Hosted-Card-Route wird verwendet.",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartCheckoutPayment"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bestehende Operation wiederhergestellt; keine zweite Zahlung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/CheckoutPayment"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "payment"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "202": {
            "description": "Operation versandt; Abschluss erfolgt asynchron.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/CheckoutPayment"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "payment"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "410": {
            "description": "Der Gateway-Verschlüsselungs-Intent oder die Bank-Challenge ist abgelaufen. Holen Sie einen frischen Intent für dieselbe Operation ein; erstellen Sie keine Ersatzzahlung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CARD_SESSION_INVALID"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/v1/payments": {
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "listOwnPaymentLinksViaPayments",
        "summary": "Eigene Zahlungslinks auflisten",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "description": "Sortiert nach createdAt DESC, id DESC. Öffentliche Links funktionieren geräteübergreifend; Auflisten erfordert ein Konto.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "nextCursor aus der vorherigen Antwort. Der Dienst verwendet base64-JSON [createdAt,id]; übergeben Sie es unverändert über URLSearchParams."
          }
        ],
        "responses": {
          "200": {
            "description": "Eine Seite eigener Zahlungslinks.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinksPage"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "invoices:read"
      },
      "post": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "createOwnPaymentLinkViaPayments",
        "summary": "Eine Rechnung mit unveränderlichen Bedingungen erstellen",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,100}$"
            },
            "description": "Ein Schlüssel pro logischer Anfrage. Eine Wiederholung mit identischer kanonischer Eingabe gibt den ursprünglichen Datensatz zurück; andere Eingabe mit demselben Schlüssel gibt 409 zurück."
          }
        ],
        "description": "Eine unveränderliche Rechnung erstellen und sofort checkoutUrl erhalten; dies belastet den Käufer nicht. USD: Karte/Alipay; RUB: SBP; USDT: Krypto. USD-Krypto bleibt aus Kompatibilitätsgründen akzeptiert, kann aber ohne USDT-Rechnung nicht bezahlt werden. Gebühren- und Mehrwertsteuer-Kundenanteile sind unabhängige Ganzzahlen von 0 bis 100; aktuelle Live-Karte/Alipay unterstützt Mehrwertsteuer-Kunde=100 und Gebühren-Kunde=0. Die Kundensumme wird nie stillschweigend geändert. Neueste Website-Anwendung muss vor einer neuen Live-Belastung genehmigt werden. Rechnungserstellung und ihr Händlerereignis committen atomar.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotente Wiederholung; replayed=true.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePaymentLinkResponse"
                }
              }
            }
          },
          "201": {
            "description": "Rechnung erstellt; replayed=false.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePaymentLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "invoices:write"
      }
    },
    "/api/v1/payments/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^lnk_[0-9a-f-]{36}$"
          },
          "description": "Kennung des eigenen Links, nicht das öffentliche Token."
        }
      ],
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "getOwnPaymentLinkViaPayments",
        "summary": "Eigener Link und gespeicherte Berechnung",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Die ID eines anderen Benutzers und eine fehlende ID geben beide 404 zurück.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [],
        "x-required-scope": "invoices:read"
      },
      "patch": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "changePaymentLinkStatusViaPayments",
        "summary": "Einen Link pausieren, fortsetzen oder abbrechen",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "parameters": [],
        "description": "Ändert nur status. Das Update und das unveränderliche Rechnungs-updated-Ereignis committen atomar. Gleichzeitige Änderungen verwenden eine Versionsprüfung; bei LINK_CHANGED aktualisieren und erneut versuchen. cancelled ist endgültig, Ablauf wird nie verlängert, und Preis, Methoden, Kostenanteile und Beschreibung bleiben eingefroren. Das Wiederholen des gespeicherten Status gibt die aktuelle Rechnung zurück.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused",
                      "cancelled"
                    ]
                  }
                },
                "required": [
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Aktueller Zustand des eigenen Links.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "invoices:write"
      }
    },
    "/api/v1/payment-links": {
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "listOwnPaymentLinksViaLinks",
        "summary": "Eigene Zahlungslinks auflisten",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "description": "Sortiert nach createdAt DESC, id DESC. Öffentliche Links funktionieren geräteübergreifend; Auflisten erfordert ein Konto.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "nextCursor aus der vorherigen Antwort. Der Dienst verwendet base64-JSON [createdAt,id]; übergeben Sie es unverändert über URLSearchParams."
          }
        ],
        "responses": {
          "200": {
            "description": "Eine Seite eigener Zahlungslinks.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinksPage"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "invoices:read"
      },
      "post": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "createOwnPaymentLinkViaLinks",
        "summary": "Eine Rechnung mit unveränderlichen Bedingungen erstellen",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,100}$"
            },
            "description": "Ein Schlüssel pro logischer Anfrage. Eine Wiederholung mit identischer kanonischer Eingabe gibt den ursprünglichen Datensatz zurück; andere Eingabe mit demselben Schlüssel gibt 409 zurück."
          }
        ],
        "description": "Eine unveränderliche Rechnung erstellen und sofort checkoutUrl erhalten; dies belastet den Käufer nicht. USD: Karte/Alipay; RUB: SBP; USDT: Krypto. USD-Krypto bleibt aus Kompatibilitätsgründen akzeptiert, kann aber ohne USDT-Rechnung nicht bezahlt werden. Gebühren- und Mehrwertsteuer-Kundenanteile sind unabhängige Ganzzahlen von 0 bis 100; aktuelle Live-Karte/Alipay unterstützt Mehrwertsteuer-Kunde=100 und Gebühren-Kunde=0. Die Kundensumme wird nie stillschweigend geändert. Neueste Website-Anwendung muss vor einer neuen Live-Belastung genehmigt werden. Rechnungserstellung und ihr Händlerereignis committen atomar.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentLink"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotente Wiederholung; replayed=true.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePaymentLinkResponse"
                }
              }
            }
          },
          "201": {
            "description": "Rechnung erstellt; replayed=false.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatePaymentLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "invoices:write"
      }
    },
    "/api/v1/payment-links/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^lnk_[0-9a-f-]{36}$"
          },
          "description": "Kennung des eigenen Links, nicht das öffentliche Token."
        }
      ],
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "getOwnPaymentLinkViaLinks",
        "summary": "Eigener Link und gespeicherte Berechnung",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Die ID eines anderen Benutzers und eine fehlende ID geben beide 404 zurück.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinkResponse"
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [],
        "x-required-scope": "invoices:read"
      },
      "patch": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "changePaymentLinkStatusViaLinks",
        "summary": "Einen Link pausieren, fortsetzen oder abbrechen",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "parameters": [],
        "description": "Ändert nur status. Das Update und das unveränderliche Rechnungs-updated-Ereignis committen atomar. Gleichzeitige Änderungen verwenden eine Versionsprüfung; bei LINK_CHANGED aktualisieren und erneut versuchen. cancelled ist endgültig, Ablauf wird nie verlängert, und Preis, Methoden, Kostenanteile und Beschreibung bleiben eingefroren. Das Wiederholen des gespeicherten Status gibt die aktuelle Rechnung zurück.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused",
                      "cancelled"
                    ]
                  }
                },
                "required": [
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Aktueller Zustand des eigenen Links.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentLinkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "invoices:write"
      }
    },
    "/api/api-keys": {
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "listMerchantKeys",
        "summary": "Eigene Schlüssel-Metadaten auflisten",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Geheimnisse und Geheimnis-Hashes werden ausgelassen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MerchantKey"
                      }
                    }
                  },
                  "required": [
                    "keys"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ]
      },
      "post": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "createMerchantKey",
        "summary": "Einen eingeschränkten Schlüssel erstellen; dessen Geheimnis einmal offenlegen",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "description": "Maximal 10 aktive Schlüssel. Höchstens 5 Erstellungen/Stunde/Benutzer. Schlüssel laufen ab, können widerrufen werden und sind auf 90 API-Anfragen/Minute/Schlüssel begrenzt.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "scopes": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 3,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "enum": [
                        "invoices:read",
                        "invoices:write",
                        "events:read"
                      ]
                    }
                  },
                  "expiresInDays": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 365,
                    "default": 90
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Speichern Sie das Geheimnis sicher auf Ihrem Server.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "$ref": "#/components/schemas/MerchantKey"
                    },
                    "secret": {
                      "type": "string",
                      "pattern": "^kv_live_[A-Za-z0-9_-]{43}$"
                    }
                  },
                  "required": [
                    "key",
                    "secret"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/api-keys/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^key_[0-9a-f-]{36}$"
          }
        }
      ],
      "delete": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "revokeMerchantKey",
        "summary": "Eigenen Schlüssel widerrufen",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "responses": {
          "200": {
            "description": "Zukünftige Verwendungen des Schlüssels werden abgelehnt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "revoked": {
                      "const": true
                    }
                  },
                  "required": [
                    "revoked"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/events": {
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "listOwnEvents",
        "summary": "Eigene unveränderliche Ereignishistorie lesen",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "parameters": [
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Unix-Zeitstempel in Millisekunden, UTC."
            },
            "description": "Legacy exklusive Zeitstempel-Grenze. Kann nicht mit Cursor kombiniert werden. Verwenden Sie nextCursor für verlustfreie Paginierung."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Undurchsichtiger nextCursor von der vorherigen Seite. Kodiert [createdAt,id] und erhält Ereignisse mit demselben Zeitstempel."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "responses": {
          "200": {
            "description": "Neueste zuerst; bis zu 50 Ereignisse. nextCursor folgen, bis null erreicht ist.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "maxItems": 50,
                      "items": {
                        "$ref": "#/components/schemas/MerchantEvent"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "events",
                    "nextCursor"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/v1/events": {
      "get": {
        "tags": [
          "Merchant API"
        ],
        "operationId": "listMerchantEventsWithKey",
        "summary": "Eigene unveränderliche Ereignishistorie lesen",
        "security": [
          {
            "merchantKey": []
          }
        ],
        "parameters": [
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Unix-Zeitstempel in Millisekunden, UTC."
            },
            "description": "Legacy exklusive Zeitstempel-Grenze. Kann nicht mit Cursor kombiniert werden. Verwenden Sie nextCursor für verlustfreie Paginierung."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Undurchsichtiger nextCursor von der vorherigen Seite. Kodiert [createdAt,id] und erhält Ereignisse mit demselben Zeitstempel."
          }
        ],
        "responses": {
          "200": {
            "description": "Neueste zuerst; bis zu 50 Ereignisse. nextCursor folgen, bis null erreicht ist.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "maxItems": 50,
                      "items": {
                        "$ref": "#/components/schemas/MerchantEvent"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "events",
                    "nextCursor"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "x-required-scope": "events:read"
      }
    },
    "/api/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhookEndpoints",
        "summary": "Endpunkte und letzte 30 Zustellungen auflisten",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Keine Signatur-Geheimnisse werden zurückgegeben.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "endpoints": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    },
                    "deliveries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "available": {
                      "type": "boolean"
                    },
                    "eventTypes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "invoice.created",
                          "invoice.updated",
                          "payment.succeeded",
                          "payment.failed",
                          "payment.refunded",
                          "payment.partially_refunded",
                          "payment.disputed",
                          "payment.review_required"
                        ]
                      }
                    }
                  },
                  "required": [
                    "endpoints",
                    "deliveries",
                    "available",
                    "eventTypes"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ]
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "createWebhookEndpoint",
        "summary": "Ein öffentliches HTTPS-Ziel registrieren",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "description": "Bis zu 5 Endpunkte und 6 Erstellungen/Stunde/Benutzer. Nur öffentliche HTTPS-Domains; keine Anmeldedaten, IP-Literale oder benutzerdefinierte Ports. Ein neu erstellter Endpunkt empfängt keine Live-Zustellungen, bis seine Challenge erfolgreich ist.",
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 8,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "enum": [
                        "invoice.created",
                        "invoice.updated",
                        "payment.succeeded",
                        "payment.failed",
                        "payment.refunded",
                        "payment.partially_refunded",
                        "payment.disputed",
                        "payment.review_required"
                      ]
                    }
                  }
                },
                "required": [
                  "url"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Das einmalige Signatur-Geheimnis speichern.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    },
                    "secret": {
                      "type": "string",
                      "pattern": "^whsec_[A-Za-z0-9_-]{43}$",
                      "description": "Nur bei Erstellung/Rotation angezeigt. Serverseitig verschlüsselt gespeichert."
                    }
                  },
                  "required": [
                    "endpoint",
                    "secret"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/webhooks/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^wh_[0-9a-f-]{36}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "getWebhookEndpoint",
        "summary": "Endpunkte und letzte 30 Zustellungen auflisten",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Keine Signatur-Geheimnisse werden zurückgegeben.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "endpoints": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    },
                    "deliveries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "available": {
                      "type": "boolean"
                    },
                    "eventTypes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "invoice.created",
                          "invoice.updated",
                          "payment.succeeded",
                          "payment.failed",
                          "payment.refunded",
                          "payment.partially_refunded",
                          "payment.disputed",
                          "payment.review_required"
                        ]
                      }
                    }
                  },
                  "required": [
                    "endpoints",
                    "deliveries",
                    "available",
                    "eventTypes"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        },
        "parameters": [
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ]
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "setWebhookStatus",
        "summary": "Einen verifizierten Endpunkt pausieren oder fortsetzen",
        "description": "Pausierte verifizierte Endpunkte behalten berechtigte Ereignisse in der Warteschlange; die Fortsetzung verarbeitet fällige Zustellungen.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "paused"
                    ]
                  }
                },
                "required": [
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status gespeichert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "updated": {
                      "const": true
                    }
                  },
                  "required": [
                    "updated"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "deleteWebhookEndpoint",
        "summary": "Endpunkt entfernen und nicht zugestellte Aufträge stornieren",
        "description": "Storniert anstehende, fehlgeschlagene und geleaste Aufträge. Eine bereits über das Netzwerk gesendete Anfrage kann nicht zurückgerufen werden.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "responses": {
          "200": {
            "description": "Endpunkt entfernt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "const": true
                    }
                  },
                  "required": [
                    "deleted"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/webhooks/{id}/verify": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^wh_[0-9a-f-]{36}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "verifyWebhookEndpoint",
        "summary": "Eine signierte Endpunkt-Verifizierungs-Challenge senden",
        "description": "Maximal 5 Verifizierungsversuche/Stunde/Benutzer. Ihr Server muss Kevmi-Signature validieren und 2xx JSON {\"challenge\":\"<data.challenge>\"} zurückgeben. Anforderungs-Timeout: 8 Sekunden; Antwortbegrenzung: 8192 Bytes. Weiterleitungen werden nicht verfolgt. Die Verifizierung aktiviert den Endpunkt.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verifiziert und aktiv.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "verified": {
                      "const": true
                    },
                    "endpoint": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "verified",
                    "endpoint"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "422": {
            "description": "Ziel konnte nicht verifiziert werden.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "WEBHOOK_UNREACHABLE",
              "WEBHOOK_VERIFICATION_FAILED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/webhooks/{id}/rotate": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^wh_[0-9a-f-]{36}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "rotateWebhookSecret",
        "summary": "Signatur-Geheimnis ersetzen und erneute Verifizierung anfordern",
        "description": "Maximal 3 Rotationen/Stunde/Benutzer. Aktualisieren Sie Ihren Server und verifizieren Sie den Endpunkt erneut. Eine bereits laufende Anfrage kann noch die vorherige Signatur tragen.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Neues Geheimnis einmal angezeigt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string",
                      "pattern": "^whsec_[A-Za-z0-9_-]{43}$",
                      "description": "Nur bei Erstellung/Rotation angezeigt. Serverseitig verschlüsselt gespeichert."
                    },
                    "requiresVerification": {
                      "const": true
                    }
                  },
                  "required": [
                    "secret",
                    "requiresVerification"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/webhooks/{id}/deliveries/{deliveryId}/retry": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^wh_[0-9a-f-]{36}$"
          }
        },
        {
          "name": "deliveryId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^del_[a-f0-9]{40}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "retryWebhookDelivery",
        "summary": "Eine fehlgeschlagene Zustellung an einen aktiven Endpunkt erneut versuchen",
        "description": "Behält Ereignis-ID und Nutzlast; erzeugt einen frischen Zeitstempel und eine frische Signatur. Jeder automatische Zustellzyklus unternimmt höchstens 6 Versuche, einschließlich abgelaufener Leasen, mit Verzögerungen von 1m, 5m, 30m, 2h und 12h. Zustellung erfolgt mindestens einmal; deduplizieren Sie Ereignis-IDs auf Ihrem Server.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Wiederholung geplant.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "const": true
                    }
                  },
                  "required": [
                    "queued"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/applications": {
      "get": {
        "tags": [
          "Applications"
        ],
        "operationId": "listOwnApplications",
        "summary": "Bis zu 30 eigene Anwendungen auflisten",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "parameters": [
          {
            "name": "X-Kevmi-Locale",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ru",
                "en",
                "es",
                "de",
                "fr",
                "pt",
                "tr",
                "kk"
              ]
            },
            "description": "Tracking-URL und Sprache der Systemmeldungen. Ohne unterstützten Wert werden Gleichherkunft-Referrer und Browsersprache berücksichtigt; Fallback ist Englisch."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "responses": {
          "200": {
            "description": "Neueste zuerst.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "applications": {
                      "type": "array",
                      "maxItems": 30,
                      "items": {
                        "$ref": "#/components/schemas/Application"
                      }
                    }
                  },
                  "required": [
                    "applications"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      },
      "post": {
        "tags": [
          "Applications"
        ],
        "operationId": "submitWebsiteApplication",
        "summary": "Website-Informationen übermitteln und eine Tracking-URL erhalten",
        "description": "Erfordert bestätigtes Telegram-Anmelden. Bis zu 5 neue Einreichungen/Tag/Benutzer. Idempotente Wiedergabe gibt 200 zurück. Der Server schreitet in echten persistierten Phasen voran; nicht verfügbare oder riskante automatische Ergebnisse erfordern menschliche Prüfung. Die Genehmigung konfiguriert das Zahlungs-Gateway nicht. Eigentum und Status können nicht vom Antragsteller angegeben werden.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,100}$"
            },
            "description": "Ein Schlüssel pro logischer Anfrage. Eine Wiederholung mit identischer kanonischer Eingabe gibt den ursprünglichen Datensatz zurück; andere Eingabe mit demselben Schlüssel gibt 409 zurück."
          },
          {
            "name": "X-Kevmi-Locale",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ru",
                "en",
                "es",
                "de",
                "fr",
                "pt",
                "tr",
                "kk"
              ]
            },
            "description": "Tracking-URL und Sprache der Systemmeldungen. Ohne unterstützten Wert werden Gleichherkunft-Referrer und Browsersprache berücksichtigt; Fallback ist Englisch."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "websiteUrl": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "Öffentliche HTTPS-Domain ohne Anmeldedaten, Abfrageparameter, IP-Literale oder benutzerdefinierte Ports. Ein Fragment wird bei der Normalisierung entfernt."
                  },
                  "businessName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "businessType": {
                    "type": "string",
                    "enum": [
                      "digital_goods",
                      "software",
                      "services",
                      "physical_goods",
                      "education",
                      "other"
                    ]
                  },
                  "description": {
                    "type": "string",
                    "minLength": 40,
                    "maxLength": 3000
                  },
                  "contactTelegram": {
                    "type": "string",
                    "description": "Ein 5–32 Zeichen langer Telegram-Benutzername, der mit einem Buchstaben beginnt, dann Buchstaben/Ziffern/Unterstriche. Optionales @ oder https://t.me/ Präfix; umgebende Leerzeichen werden entfernt. Gespeichert als @username."
                  },
                  "consent": {
                    "type": "boolean",
                    "const": true
                  }
                },
                "required": [
                  "websiteUrl",
                  "businessName",
                  "businessType",
                  "description",
                  "contactTelegram",
                  "consent"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bestehende Einreichung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "application",
                    "url",
                    "replayed"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "202": {
            "description": "Akzeptiert; Verarbeitung läuft auf dem Server weiter.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "application",
                    "url",
                    "replayed"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/applications/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^app_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Applications"
        ],
        "operationId": "getOwnApplication",
        "summary": "Eigene Prüfphasen und Ereignishistorie lesen",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "parameters": [
          {
            "name": "X-Kevmi-Locale",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ru",
                "en",
                "es",
                "de",
                "fr",
                "pt",
                "tr",
                "kk"
              ]
            },
            "description": "Tracking-URL und Sprache der Systemmeldungen. Ohne unterstützten Wert werden Gleichherkunft-Referrer und Browsersprache berücksichtigt; Fallback ist Englisch."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "responses": {
          "200": {
            "description": "Private Antragsteller-Projektion. Beweise und Modellausgabe werden nicht offengelegt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    },
                    "events": {
                      "type": "array",
                      "maxItems": 40,
                      "items": {
                        "$ref": "#/components/schemas/ApplicationEvent"
                      }
                    }
                  },
                  "required": [
                    "application",
                    "events"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/applications/{id}/resume": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^app_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Applications"
        ],
        "operationId": "resumeApplicationJob",
        "summary": "Eine berechtigte Hintergrundphase fortsetzen",
        "description": "Prüfung kann nicht übersprungen oder eine Phase genehmigt werden. Eine Server-Lease verhindert doppelte Arbeit. Überprüfungsbedürftige und finale Anwendungen bleiben unverändert. Höchstens 30 Verarbeitungs-Fortsetzungs-Anfragen/Minute/Benutzer.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          },
          {
            "name": "X-Kevmi-Locale",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ru",
                "en",
                "es",
                "de",
                "fr",
                "pt",
                "tr",
                "kk"
              ]
            },
            "description": "Tracking-URL und Sprache der Systemmeldungen. Ohne unterstützten Wert werden Gleichherkunft-Referrer und Browsersprache berücksichtigt; Fallback ist Englisch."
          },
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^sto_[A-Za-z0-9_-]+$"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Keine Verarbeitung erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    }
                  },
                  "required": [
                    "application"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "202": {
            "description": "Verarbeitung geplant.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    },
                    "scheduled": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "application",
                    "scheduled"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/moderation/applications": {
      "get": {
        "tags": [
          "Moderation"
        ],
        "operationId": "listModerationApplications",
        "summary": "Bis zu 100 Anwendungen zur Moderation auflisten",
        "description": "Erfordert, dass die authentifizierte Telegram-Identität in MODERATOR_TELEGRAM_IDS ist. Enthält alle Status, sortiert nach needs_review zuerst, processing zweit, dann finale Status; neueste Aktualisierungen zuerst innerhalb einer Gruppe.",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Moderator-Warteschlange.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "applications": {
                      "type": "array",
                      "maxItems": 100,
                      "items": {
                        "$ref": "#/components/schemas/Application"
                      }
                    }
                  },
                  "required": [
                    "applications"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/moderation/applications/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^app_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
          }
        }
      ],
      "get": {
        "tags": [
          "Moderation"
        ],
        "operationId": "getModerationApplication",
        "summary": "Prüf-Beweise und Phasenhistorie lesen",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Private Moderator-Beweise.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    },
                    "events": {
                      "type": "array",
                      "maxItems": 40,
                      "items": {
                        "$ref": "#/components/schemas/ApplicationEvent"
                      }
                    },
                    "evidence": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "required": [
                    "application",
                    "events",
                    "evidence"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/moderation/applications/{id}/decision": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^app_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
          }
        }
      ],
      "post": {
        "tags": [
          "Moderation"
        ],
        "operationId": "decideApplicationStage",
        "summary": "Die aktuelle Prüfphase genehmigen oder mit einem öffentlichen Grund ablehnen",
        "description": "Erfordert einen konfigurierten Moderator; höchstens 30 Entscheidungen/Minute/Benutzer. expectedVersion wird atomar verglichen. Nur die aktuelle needs_review-Phase kann genehmigt werden; endgültige Anträge können nicht stillschweigend wieder geöffnet werden. Eine Ablehnung erfordert einen bearbeitbaren öffentlichen Grund. Die Entscheidung, der Phasenverlauf und die aktivierte Antragsbenachrichtigung werden zusammen gespeichert.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "expectedVersion": {
                        "type": "integer",
                        "minimum": 1
                      },
                      "action": {
                        "type": "string",
                        "const": "approve_step"
                      },
                      "reason": {
                        "type": "string",
                        "maxLength": 0
                      }
                    },
                    "required": [
                      "expectedVersion",
                      "action"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "expectedVersion": {
                        "type": "integer",
                        "minimum": 1
                      },
                      "action": {
                        "type": "string",
                        "const": "reject"
                      },
                      "reason": {
                        "type": "string",
                        "minLength": 10,
                        "maxLength": 1500
                      }
                    },
                    "required": [
                      "expectedVersion",
                      "action",
                      "reason"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Entscheidung gespeichert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "application": {
                      "$ref": "#/components/schemas/Application"
                    }
                  },
                  "required": [
                    "application"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/gateway/webhook": {
      "post": {
        "tags": [
          "Gateway events"
        ],
        "operationId": "receiveGatewayEvent",
        "summary": "Signierte, quellnative Gateway-Ereignisse empfangen",
        "description": "Nativ v3: X-Gateway-Timestamp (Unix-Sekunden), X-Gateway-Signature und passende X-Gateway-Event-Id angeben. Maximale Zeitabweichung: 300 Sekunden. Nach der Signaturprüfung ruft Kevmi die Zahlung über die authentifizierte Gateway-API ab, prüft die gespeicherte Bestellung, die exakte Währung/den Betrag, die Methode und den vom Anbieter bestätigten Status und speichert dann atomar die Quittung und das Merchant-Outbox-Ereignis. Webhook-Text und Browser-Beobachtungen allein bestätigen niemals eine Zahlung. Wiederholte IDs werden dedupliziert; ein geänderter Inhalt für eine vorhandene ID wird abgelehnt. Verzögerte Ereignisse verwenden aktuellen autoritativen Status. Teilrückerstattungen, vollständige Rückerstattungen, Streitfälle und Prüfstatus werden unterstützt. Nicht gebundene Bestellungen werden quittiert und ignoriert. Legacy-normalisierte Ereignisse mit Kevmi-Signature werden weiterhin separat unterstützt; nur deren succeeded/failed/full-refunded-Übergänge gelten.",
        "security": [
          {
            "nativeGatewaySignature": []
          },
          {
            "gatewaySignature": []
          }
        ],
        "parameters": [
          {
            "name": "X-Gateway-Timestamp",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{10}$"
            },
            "description": "Erforderlich für native v3-Ereignisse."
          },
          {
            "name": "X-Gateway-Event-Id",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Erforderlich für natives v3; muss mit body.id übereinstimmen."
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Exakter signierter JSON-Text; natives v3-Limit: 524288 Bytes. Vor der Signaturprüfung nicht parsen und neu serialisieren.",
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/NativeGatewayEvent"
                  },
                  {
                    "$ref": "#/components/schemas/LegacyGatewayEvent"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Empfangen, dedupliziert oder sicher ignoriert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "received": {
                      "type": "boolean",
                      "const": true
                    },
                    "replayed": {
                      "type": "boolean"
                    },
                    "ignored": {
                      "type": "boolean"
                    },
                    "applied": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "received"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Die Gateway-Signatur fehlt, ist ungültig oder liegt außerhalb des akzeptierten Zeitfensters.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_GATEWAY_SIGNATURE",
              "INVALID_SIGNATURE",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Eine Ereignis-ID wurde mit geändertem Inhalt wiederverwendet, oder eine Zahlungs-ID kollidiert mit der gespeicherten Rechnungsbindung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_EVENT_CONFLICT",
              "PAYMENT_ID_CONFLICT"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Das Gateway ist ausgelastet; Webhook-Zustellung mit derselben Ereignis-ID erneut versuchen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_BUSY"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Die Gateway-Konfiguration oder das Signaturgeheimnis fehlt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_NOT_CONNECTED",
              "DATABASE_NOT_CONFIGURED"
            ]
          }
        }
      }
    },
    "/api/jobs/dispatch": {
      "post": {
        "tags": [
          "Service"
        ],
        "operationId": "dispatchBackgroundJobs",
        "summary": "Fällige Zustell- und Anwendungsaufträge ausführen",
        "description": "Server-Scheduler-Einstiegspunkt. Erfordert JOBS_SECRET, keine Browser-Sitzung oder Merchant-Schlüssel. Akzeptiert keine Auftrags-IDs oder beliebige ausgehende URLs.",
        "security": [
          {
            "jobSecret": []
          }
        ],
        "responses": {
          "200": {
            "description": "Ohne Hintergrundkontext abgeschlossen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "202": {
            "description": "In einem Hintergrundausführungskontext akzeptiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "const": true
                    }
                  },
                  "required": [
                    "accepted"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}/status": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "get": {
        "tags": [
          "Checkout"
        ],
        "operationId": "getCheckoutPaymentStatus",
        "summary": "Dieselbe Zahlung lesen und aktualisieren",
        "description": "Kein Konto erforderlich. Aktualisiert einen vorhandenen Vorgang über authentifizierten Gateway-Transport mit serverseitiger Drosselung. Es wird keine neue Zahlung erstellt. Gibt null zurück, wenn nichts gesendet wurde. Bestätigen Sie eine Bestellung nur, wenn fulfillmentReady true ist.",
        "responses": {
          "200": {
            "description": "Aktueller bereinigter Zahlungsstatus.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/CheckoutPayment"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "payment"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}/reconcile": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "post": {
        "tags": [
          "Checkout"
        ],
        "operationId": "reconcileCheckoutPayment",
        "summary": "Eine autoritative Statusabgleichung anfordern",
        "description": "Liest den vorhandenen Vorgang und bittet das Gateway, seinen Anbieterstatus abzugleichen. Erstellt keine Zahlung. Höchstens 3 Anfragen pro Rechnung pro Minute. Verfügbar für bereits versendete Zahlungen, auch wenn die Rechnung nicht mehr aktiv ist.",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyObject"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Abgeglichene Zahlung oder null.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/CheckoutPayment"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "payment"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "410": {
            "description": "Der Gateway-Verschlüsselungs-Intent oder die Bank-Challenge ist abgelaufen. Holen Sie einen frischen Intent für dieselbe Operation ein; erstellen Sie keine Ersatzzahlung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CARD_SESSION_INVALID"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}/card-intent": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "post": {
        "tags": [
          "Checkout"
        ],
        "operationId": "createCardEncryptionIntent",
        "summary": "Einen öffentlichen Gateway-Schlüssel und eine gebundene Verschlüsselungsabsicht erhalten",
        "description": "Nur das Gateway besitzt den privaten Schlüssel. Eine Absicht läuft innerhalb von fünf Minuten ab und bindet die Merchant-Bestellung, Währung, Basis-/Gesamtbeträge, den Idempotenzschlüssel des Vorgangs und den Zweck. Zahlungsabsichten erfordern eine aktive Rechnung und einen genehmigten Merchant; Code-Absichten erfordern eine vorhandene, aktuelle Bankherausforderung. Keine PAN, CVV, Bankcode oder private JWK-Felder werden von diesem Endpunkt akzeptiert. Höchstens 8 Absichten pro Rechnung und 12 pro Client pro Minute. Der verschlüsselte Klartext ist {intent,name,country,email?,card:{number,expiration,cvv,holder}} für Zahlungen oder {intent,code} für Code. Der Klartext wird nur im Browser vor der JWE-Verschlüsselung zusammengesetzt.",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt, höchstens 2048 Bytes.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "purpose": {
                    "type": "string",
                    "enum": [
                      "payment",
                      "code"
                    ],
                    "default": "payment"
                  }
                },
                "required": [],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur kurzlebige Absicht und öffentlicher RSA-Schlüssel.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardIntent"
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "410": {
            "description": "Der Gateway-Verschlüsselungs-Intent oder die Bank-Challenge ist abgelaufen. Holen Sie einen frischen Intent für dieselbe Operation ein; erstellen Sie keine Ersatzzahlung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CARD_SESSION_INVALID"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}/code": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "post": {
        "tags": [
          "Checkout"
        ],
        "operationId": "submitEncryptedBankCode",
        "summary": "Einen verschlüsselten Code für die aktuelle Bankherausforderung weiterleiten",
        "description": "Eine Absicht mit Zweck=code abrufen und {intent,code} im Browser verschlüsseln. Das Gateway validiert die aktuelle Herausforderung und verbraucht die versiegelte Absicht einmal. Kevmi erhält niemals Klartext-Code. Höchstens 5 Übermittlungen pro Rechnung pro Minute; Status nach einer unsicheren Antwort aktualisieren.",
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sealed": {
                    "$ref": "#/components/schemas/SealedCardData"
                  }
                },
                "required": [
                  "sealed"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Code gesendet; aktueller Zahlungsstatus.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/CheckoutPayment"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "payment"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "410": {
            "description": "Der Gateway-Verschlüsselungs-Intent oder die Bank-Challenge ist abgelaufen. Holen Sie einen frischen Intent für dieselbe Operation ein; erstellen Sie keine Ersatzzahlung.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CARD_SESSION_INVALID"
            ]
          },
          "413": {
            "description": "Body überschreitet 16.384 Byte; das Limit beträgt 65.536 Byte für /api/support/ask und den Telegram-Webhook.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "REQUEST_TOO_LARGE"
            ]
          },
          "415": {
            "description": "Content-Type: application/json ist erforderlich.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "JSON_REQUIRED"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/checkout/{token}/crypto-services": {
      "parameters": [
        {
          "name": "token",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "description": "Zufällige öffentliche Kennung aus der Checkout-URL. Gewährt Lesezugriff nur auf diese Rechnung."
        }
      ],
      "get": {
        "tags": [
          "Checkout"
        ],
        "operationId": "getCheckoutCryptoServices",
        "summary": "Den aktuellen Coin- und Netzwerkkatalog lesen",
        "description": "Nur für eine USDT-Rechnung, die Krypto erlaubt. Die Rechnung bleibt in USDT denominiert; das Gateway bietet die gewählte Zahler-Münze an. Gehen Sie niemals davon aus, dass USD USDT entspricht, und konvertieren Sie den Überweisungsbetrag nicht in eine Gleitkommazahl. Höchstens 10 Kataloglesungen pro Rechnung pro Minute.",
        "responses": {
          "200": {
            "description": "Vom Gateway bereitgestellter Katalog mit aktueller Verfügbarkeit und Überweisungslimits.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "services": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "currency": {
                            "type": "string"
                          },
                          "network": {
                            "type": "string"
                          },
                          "networkLabel": {
                            "type": "string"
                          },
                          "available": {
                            "type": "boolean"
                          },
                          "minAmount": {
                            "type": "string",
                            "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
                            "description": "Exakter Dezimalwert in der gewählten Überweisungs-Münze."
                          },
                          "maxAmount": {
                            "type": "string",
                            "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
                            "description": "Exakter Dezimalwert in der gewählten Überweisungs-Münze."
                          },
                          "confirmations": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "minimum": 0
                          }
                        },
                        "required": [
                          "currency",
                          "network",
                          "networkLabel",
                          "available",
                          "minAmount",
                          "maxAmount",
                          "confirmations"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "fetchedAt": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Unix-Zeitstempel in Millisekunden, UTC."
                    }
                  },
                  "required": [
                    "services",
                    "fetchedAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "502": {
            "description": "Gateway-Antwort nicht verfügbar, fehlerhaft oder nicht überprüfbar. Lesen Sie den bestehenden Zahlungsstatus, bevor Sie einen erneuten Versuch unternehmen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "GATEWAY_REQUEST_UNCERTAIN",
              "GATEWAY_INVALID_RESPONSE"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/stores": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "listStores",
        "summary": "Alle Geschäfte auflisten, die dem aktuellen Konto gehören",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Geschäfts-IDs unterscheiden sich von Konto-IDs. Es werden keine Geheimnisse offengelegt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stores": {
                      "type": "array",
                      "maxItems": 100,
                      "items": {
                        "$ref": "#/components/schemas/Store"
                      }
                    },
                    "defaultStoreId": {
                      "type": "string",
                      "pattern": "^sto_[A-Za-z0-9_-]+$"
                    }
                  },
                  "required": [
                    "stores",
                    "defaultStoreId"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      },
      "post": {
        "tags": [
          "Account"
        ],
        "operationId": "createStore",
        "summary": "Ein separates Geschäft erstellen",
        "description": "Bis zu 100 Geschäfte/Konto und 10 Erstellungen/Stunde/Konto. Ein neues Geschäft benötigt eine eigene Website-Genehmigung, bevor eine Zahlung gestartet wird.",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Erstellt.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "store": {
                      "$ref": "#/components/schemas/Store"
                    }
                  },
                  "required": [
                    "store"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "409": {
            "description": "Die Anmeldungsanfrage wird verwendet oder abgebrochen, die Identität ist nicht bestätigt oder eine Support-Anfrage kollidiert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "CHALLENGE_UNAVAILABLE",
              "IDENTITY_INCOMPLETE",
              "TICKET_CONFLICT",
              "IDEMPOTENCY_CONFLICT",
              "LINK_CANCELLED",
              "LINK_EXPIRED",
              "LINK_UNAVAILABLE"
            ]
          },
          "429": {
            "description": "Ratenlimit überschritten.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Retry-After": {
                "schema": {
                  "type": "string",
                  "const": "60"
                },
                "description": "Der Server gibt immer 60 zurück; dies garantiert nicht, dass ein Stundenkontingent abgelaufen ist."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "RATE_LIMITED"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/stores/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^sto_[A-Za-z0-9_-]+$"
          }
        }
      ],
      "patch": {
        "tags": [
          "Account"
        ],
        "operationId": "updateStore",
        "summary": "Ein eigenes Geschäft umbenennen oder dessen MwSt-Standardwert ändern",
        "security": [
          {
            "cookieSession": [],
            "csrfToken": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "description": "Muss exakt mit APP_ORIGIN übereinstimmen. Sec-Fetch-Site: cross-site wird abgelehnt. Der Server bietet keinen CORS-Zugriff.",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "description": "Aktuelles Sitzungstoken von GET /api/auth/me oder erfolgreichem Abschluss der Anmeldung.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "vatPayer": {
                    "type": "string",
                    "enum": [
                      "customer",
                      "merchant"
                    ]
                  }
                },
                "required": [],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bestehende Rechnungsangebote bleiben unverändert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "store": {
                      "$ref": "#/components/schemas/Store"
                    }
                  },
                  "required": [
                    "store"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "403": {
            "description": "Origin-, CSRF- oder Browser-Bindungsvalidierung fehlgeschlagen.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_ORIGIN",
              "CSRF_REQUIRED",
              "BROWSER_PROOF_REQUIRED",
              "INVALID_CHALLENGE"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/exchange-rates": {
      "get": {
        "tags": [
          "Payments"
        ],
        "operationId": "getReferenceExchangeRate",
        "summary": "Den aktuellen USD/RUB-Referenzkurs abrufen",
        "description": "Serverseitig für eine Stunde zwischengespeichert. Der numerische Kurs verwendet Millionstel RUB pro USD. Es wird kein Ersatzangebot erfunden. Wird bei der Rechnungserstellung verwendet; eine bestehende Rechnung behält ihren eigenen Kurs.",
        "security": [],
        "responses": {
          "200": {
            "description": "Offizielle Quelle, Veröffentlichungsdatum und Abrufzeit.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rate": {
                      "$ref": "#/components/schemas/ExchangeRate"
                    }
                  },
                  "required": [
                    "rate"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    },
    "/api/account/dashboard": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccountDashboard",
        "summary": "Verifizierte Zahlungseingänge für ein Geschäft oder alle eigenen Geschäfte lesen",
        "description": "Netto-Zahlungseingänge sind kein abhebbarer Saldo. Legacy-Währungen bleiben getrennt. Summen gelten für alle Zeiten; Tages-/Methodenaufschlüsselungen verwenden den angeforderten UTC-Zeitraum.",
        "security": [
          {
            "cookieSession": []
          }
        ],
        "parameters": [
          {
            "name": "X-Kevmi-Store",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Wählen Sie ein eigenes Geschäft für eine Browser-Sitzung aus. Lassen Sie es weg, um das erste Geschäft zu verwenden. API-Schlüssel ignorieren diesen Header und verwenden immer ihre unveränderliche Geschäftsbindung. Der Wert all ist schreibgeschützt und wird nur von den Dashboard- und Rechnungslisten-Endpunkten unterstützt."
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                7,
                30
              ],
              "default": 7
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Schreibgeschützte Buchungsübersicht.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "storeId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "stores": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "pattern": "^sto_[A-Za-z0-9_-]+$"
                          },
                          "name": {
                            "type": "string"
                          },
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "invoices": {
                            "type": "integer"
                          },
                          "netMinor": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991,
                            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "currency",
                          "invoices",
                          "netMinor"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "totals": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "currency": {
                            "type": "string"
                          },
                          "invoices": {
                            "type": "integer"
                          },
                          "succeeded": {
                            "type": "integer"
                          },
                          "grossMinor": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991,
                            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
                          },
                          "netMinor": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991,
                            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
                          }
                        },
                        "required": [
                          "currency",
                          "invoices",
                          "succeeded",
                          "grossMinor",
                          "netMinor"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "daily": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "currency": {
                            "type": "string"
                          },
                          "day": {
                            "type": "string"
                          },
                          "count": {
                            "type": "integer"
                          },
                          "grossMinor": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991,
                            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
                          }
                        },
                        "required": [
                          "currency",
                          "day",
                          "count",
                          "grossMinor"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "methods": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "currency": {
                            "type": "string"
                          },
                          "method": {
                            "type": "string"
                          },
                          "count": {
                            "type": "integer"
                          },
                          "grossMinor": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991,
                            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
                          }
                        },
                        "required": [
                          "currency",
                          "method",
                          "count",
                          "grossMinor"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "days": {
                      "type": "integer",
                      "enum": [
                        7,
                        30
                      ]
                    },
                    "from": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Unix-Zeitstempel in Millisekunden, UTC."
                    },
                    "generatedAt": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Unix-Zeitstempel in Millisekunden, UTC."
                    },
                    "accountingBasis": {
                      "type": "string",
                      "const": "verified_receipts"
                    },
                    "withdrawableBalance": {
                      "type": "null"
                    },
                    "payoutCreationAvailable": {
                      "type": "boolean",
                      "const": false
                    }
                  },
                  "required": [
                    "storeId",
                    "stores",
                    "totals",
                    "daily",
                    "methods",
                    "days",
                    "from",
                    "generatedAt",
                    "accountingBasis",
                    "withdrawableBalance",
                    "payoutCreationAvailable"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Ungültiges JSON, unbekanntes Feld oder ungültiger Wert.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVALID_JSON",
              "UNKNOWN_FIELD",
              "INVALID_INPUT",
              "INVALID_VAT_PAYER",
              "INVALID_NOTIFICATIONS",
              "INVALID_TICKET_STATUS",
              "INVALID_UPDATE",
              "INVALID_HISTORY",
              "INVALID_PAGE_CONTEXT",
              "INVALID_LOCALE",
              "INVALID_FILTER",
              "INVALID_NOTIFICATION_SELECTION",
              "INVALID_AMOUNT",
              "INVALID_CURRENCY",
              "INVALID_METHODS",
              "INVALID_EXPIRY",
              "INVALID_QUOTE",
              "INVALID_LIMIT",
              "INVALID_CURSOR",
              "INVALID_STATUS",
              "IDEMPOTENCY_KEY_REQUIRED",
              "METHOD_UNAVAILABLE"
            ]
          },
          "401": {
            "description": "Keine gültige Sitzung; für einen Webhook ein ungültiges Geheimnis.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "AUTH_REQUIRED",
              "SESSION_EXPIRED",
              "WEBHOOK_UNAUTHORIZED"
            ]
          },
          "404": {
            "description": "Der Datensatz fehlt, das öffentliche Token ist ungültig oder der angeforderte Datensatz gehört einem anderen Benutzer.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "TICKET_NOT_FOUND",
              "LINK_NOT_FOUND"
            ]
          },
          "503": {
            "description": "Eine Integration oder Speicherung ist nicht verfügbar, ein Ereignis wird verarbeitet oder der Dienst ist nicht verfügbar.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATABASE_NOT_CONFIGURED",
              "ORIGIN_NOT_CONFIGURED",
              "TELEGRAM_NOT_CONFIGURED",
              "UPDATE_IN_PROGRESS",
              "SERVICE_UNAVAILABLE",
              "GATEWAY_NOT_CONNECTED"
            ]
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "cookieSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-kevmi-session",
        "description": "Zufälliges Sitzungs-Token, Secure/HttpOnly/SameSite=Lax, 24 Stunden gültig. Ein Hash wird in der Datenbank gespeichert. Wird nur nach verifizierter Telegram-Anmeldung ausgegeben."
      },
      "browserProof": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-kevmi-login",
        "description": "HttpOnly-Cookie von Anfang an: challengeId.proof, 300 Sekunden gültig. Vom Telegram-Deep-Link ausgeschlossen."
      },
      "csrfToken": {
        "type": "apiKey",
        "in": "header",
        "name": "X-CSRF-Token",
        "description": "Sitzungs-CSRF-Token, ausgegeben von /api/auth/me oder /api/auth/telegram/complete. Mutationen erfordern auch den exakten Origin."
      },
      "telegramWebhookSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Telegram-Bot-Api-Secret-Token",
        "description": "Separates serverkonfiguriertes Webhook-Geheimnis. Sein Wert ist privat. Dies ist nicht das Bot-Token."
      },
      "merchantKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "kv_live_…",
        "description": "Bereichsgebundener Merchant-API-Schlüssel. Nur sein Hash wird gespeichert. Nur für Server-zu-Server-Nutzung; niemals in einem Widget oder Browser-Bundle platzieren."
      },
      "gatewaySignature": {
        "type": "apiKey",
        "in": "header",
        "name": "Kevmi-Signature",
        "description": "t=<Unix-Sekunden>,v1=<hex HMAC-SHA256(secret, timestamp + Punkt + exakter UTF-8-Anforderungstext)>. Maximale Zeitabweichung: 300 Sekunden."
      },
      "jobSecret": {
        "type": "http",
        "scheme": "bearer",
        "description": "Separates, nur für Server bestimmtes JOBS_SECRET. Kein Merchant-API-Schlüssel."
      },
      "nativeGatewaySignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Gateway-Signature",
        "description": "v1=<hex HMAC-SHA256(GATEWAY_WEBHOOK_SECRET, timestamp + \".\" + exakter roher UTF-8-Text)>; getrennt von Merchant Kevmi-Signature."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "EmptyObject": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "Config": {
        "type": "object",
        "properties": {
          "telegram": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "botUsername": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "enabled",
              "botUsername"
            ],
            "additionalProperties": false
          },
          "support": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "search",
                  "ai"
                ]
              },
              "available": {
                "type": "boolean",
                "const": true
              }
            },
            "required": [
              "mode",
              "available"
            ],
            "additionalProperties": false
          },
          "gateway": {
            "type": "object",
            "properties": {
              "configured": {
                "type": "boolean"
              },
              "connected": {
                "type": "boolean",
                "const": false,
                "description": "Der öffentliche Konfigurations-Endpunkt prüft nicht die Gateway-Gesundheit. Konfiguration ist keine erfolgreiche Live-Verbindungsprüfung."
              },
              "status": {
                "type": "string",
                "enum": [
                  "configured",
                  "not_configured"
                ]
              }
            },
            "required": [
              "configured",
              "connected",
              "status"
            ],
            "additionalProperties": false
          },
          "capabilities": {
            "type": "object",
            "properties": {
              "server": {
                "type": "boolean",
                "const": true
              },
              "account": {
                "type": "boolean"
              },
              "notifications": {
                "type": "boolean"
              },
              "tickets": {
                "type": "boolean"
              },
              "directPaymentsOnly": {
                "type": "boolean",
                "const": true
              },
              "paymentLinks": {
                "type": "boolean",
                "description": "D1 ist für Serverrechnungen konfiguriert. Dies zeigt keine Zahlungsbereitschaft an."
              },
              "apiKeys": {
                "type": "boolean"
              },
              "webhooks": {
                "type": "boolean"
              },
              "widgets": {
                "type": "boolean"
              },
              "applications": {
                "type": "boolean"
              },
              "applicationNotifications": {
                "type": "boolean"
              }
            },
            "required": [
              "server",
              "account",
              "notifications",
              "tickets",
              "directPaymentsOnly",
              "paymentLinks",
              "apiKeys",
              "webhooks",
              "widgets",
              "applications",
              "applicationNotifications"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "telegram",
          "support",
          "gateway",
          "capabilities"
        ],
        "additionalProperties": false
      },
      "Health": {
        "type": "object",
        "properties": {
          "telegram": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "botUsername": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "enabled",
              "botUsername"
            ],
            "additionalProperties": false
          },
          "support": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "search",
                  "ai"
                ]
              },
              "available": {
                "type": "boolean",
                "const": true
              }
            },
            "required": [
              "mode",
              "available"
            ],
            "additionalProperties": false
          },
          "gateway": {
            "type": "object",
            "properties": {
              "configured": {
                "type": "boolean"
              },
              "connected": {
                "type": "boolean",
                "const": false,
                "description": "Der öffentliche Konfigurations-Endpunkt prüft nicht die Gateway-Gesundheit. Konfiguration ist keine erfolgreiche Live-Verbindungsprüfung."
              },
              "status": {
                "type": "string",
                "enum": [
                  "configured",
                  "not_configured"
                ]
              }
            },
            "required": [
              "configured",
              "connected",
              "status"
            ],
            "additionalProperties": false
          },
          "capabilities": {
            "type": "object",
            "properties": {
              "server": {
                "type": "boolean",
                "const": true
              },
              "account": {
                "type": "boolean"
              },
              "notifications": {
                "type": "boolean"
              },
              "tickets": {
                "type": "boolean"
              },
              "directPaymentsOnly": {
                "type": "boolean",
                "const": true
              },
              "paymentLinks": {
                "type": "boolean",
                "description": "D1 ist für Serverrechnungen konfiguriert. Dies zeigt keine Zahlungsbereitschaft an."
              },
              "apiKeys": {
                "type": "boolean"
              },
              "webhooks": {
                "type": "boolean"
              },
              "widgets": {
                "type": "boolean"
              },
              "applications": {
                "type": "boolean"
              },
              "applicationNotifications": {
                "type": "boolean"
              }
            },
            "required": [
              "server",
              "account",
              "notifications",
              "tickets",
              "directPaymentsOnly",
              "paymentLinks",
              "apiKeys",
              "webhooks",
              "widgets",
              "applications",
              "applicationNotifications"
            ],
            "additionalProperties": false
          },
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "storage": {
            "type": "string",
            "enum": [
              "ready",
              "not_configured",
              "unavailable"
            ]
          }
        },
        "required": [
          "telegram",
          "support",
          "gateway",
          "capabilities",
          "status",
          "storage"
        ],
        "additionalProperties": false
      },
      "NotificationPreferences": {
        "type": "object",
        "properties": {
          "payments": {
            "type": "boolean"
          },
          "payouts": {
            "type": "boolean"
          },
          "support": {
            "type": "boolean"
          },
          "security": {
            "type": "boolean"
          }
        },
        "required": [
          "payments",
          "payouts",
          "support",
          "security"
        ],
        "additionalProperties": false
      },
      "SettingsPatch": {
        "type": "object",
        "properties": {
          "storeName": {
            "type": "string",
            "minLength": 1,
            "x-trimmedMaxLength": 80,
            "x-trimmedMinLength": 1,
            "description": "Umgebende Leerzeichen werden entfernt. Länge nach dem Entfernen: 1–80 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant"
            ]
          },
          "notifications": {
            "type": "object",
            "properties": {
              "payments": {
                "type": "boolean"
              },
              "payouts": {
                "type": "boolean"
              },
              "support": {
                "type": "boolean"
              },
              "security": {
                "type": "boolean"
              }
            },
            "required": [],
            "additionalProperties": false
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "username": {
            "type": [
              "string",
              "null"
            ]
          },
          "storeName": {
            "type": "string"
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant"
            ]
          },
          "notifications": {
            "$ref": "#/components/schemas/NotificationPreferences"
          },
          "isModerator": {
            "type": "boolean",
            "description": "Ob diese Telegram-Identität zur konfigurierten Moderator-Allowlist gehört."
          }
        },
        "required": [
          "id",
          "displayName",
          "username",
          "storeName",
          "vatPayer",
          "notifications",
          "isModerator"
        ],
        "additionalProperties": false
      },
      "UserResponse": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/User"
          }
        },
        "required": [
          "user"
        ],
        "additionalProperties": false
      },
      "Anonymous": {
        "type": "object",
        "properties": {
          "authenticated": {
            "type": "boolean",
            "const": false
          }
        },
        "required": [
          "authenticated"
        ],
        "additionalProperties": false
      },
      "CurrentSession": {
        "type": "object",
        "properties": {
          "authenticated": {
            "type": "boolean",
            "const": true
          },
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "csrfToken": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "authenticated",
          "user",
          "csrfToken",
          "expiresAt"
        ],
        "additionalProperties": false
      },
      "LoginChallenge": {
        "type": "object",
        "properties": {
          "challengeId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "code": {
            "type": "string",
            "pattern": "^[0-9]{6}$"
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "telegramUrl": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://t\\.me/"
          }
        },
        "required": [
          "challengeId",
          "code",
          "expiresAt",
          "telegramUrl"
        ],
        "additionalProperties": false
      },
      "CompletedLogin": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "authenticated"
          },
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "csrfToken": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "status",
          "user",
          "csrfToken",
          "expiresAt"
        ],
        "additionalProperties": false
      },
      "SupportQuestion": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "minLength": 2,
            "x-trimmedMaxLength": 2000,
            "x-trimmedMinLength": 2,
            "description": "Umgebende Leerzeichen werden entfernt. Länge nach dem Entfernen: 2–2.000 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
          },
          "locale": {
            "type": "string",
            "enum": [
              "ru",
              "en",
              "es",
              "de",
              "fr",
              "pt",
              "tr",
              "kk"
            ],
            "default": "en",
            "description": "Antwortsprache. Wenn weggelassen, werden unterstützte Accept-Language-Präferenzen verwendet; sonst Englisch. Dokumentation ist in jeder unterstützten Schnittstellensprache verfügbar."
          },
          "history": {
            "type": "array",
            "maxItems": 6,
            "description": "Bis zu den letzten drei Frage-Antwort-Paaren. Optional. Nicht vertrauenswürdiger Kontext, keine Provider-Systemrollen-Nachrichten.",
            "items": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string",
                      "const": "user"
                    },
                    "content": {
                      "type": "string",
                      "minLength": 1,
                      "x-trimmedMaxLength": 1800,
                      "x-trimmedMinLength": 1,
                      "description": "Umgebende Leerzeichen werden entfernt. Länge nach dem Entfernen: 1–1.800 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
                    }
                  },
                  "required": [
                    "role",
                    "content"
                  ],
                  "additionalProperties": false
                },
                {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string",
                      "const": "assistant"
                    },
                    "content": {
                      "type": "string",
                      "minLength": 1,
                      "x-trimmedMaxLength": 3000,
                      "x-trimmedMinLength": 1,
                      "description": "Umgebende Leerzeichen werden entfernt. Länge nach dem Entfernen: 1–3.000 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
                    }
                  },
                  "required": [
                    "role",
                    "content"
                  ],
                  "additionalProperties": false
                }
              ]
            }
          },
          "pageContext": {
            "type": "string",
            "minLength": 1,
            "x-trimmedMaxLength": 80,
            "x-trimmedMinLength": 1,
            "description": "Kurze Abschnittsbezeichnung nach dem Entfernen, 1–80 Zeichen. Erlaubt Buchstaben, Ziffern, Leerzeichen und ·.,—–-:(). Zeilenumbrüche, URLs, Abfrageparameter und HTML sind verboten. Keine Tokens oder Geheimnisse einschließen.",
            "pattern": "^[\\p{L}\\p{N}\\s·.,—–\\-:()]+$",
            "not": {
              "pattern": "[\\r\\n]"
            }
          }
        },
        "required": [
          "question"
        ],
        "additionalProperties": false
      },
      "SupportSource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "pattern": "^/(?:ru/|en/)?docs/[^/]+$",
            "description": "Relativer Link zu einem veröffentlichten Wissensartikel."
          }
        },
        "required": [
          "id",
          "title",
          "url"
        ],
        "additionalProperties": false
      },
      "SearchSupportAnswer": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "const": "search"
          },
          "answer": {
            "type": "string"
          },
          "sources": {
            "type": "array",
            "maxItems": 3,
            "items": {
              "$ref": "#/components/schemas/SupportSource"
            }
          },
          "knowledgeVersion": {
            "type": [
              "string",
              "null"
            ]
          },
          "needsHuman": {
            "type": "boolean"
          },
          "aiUnavailable": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "mode",
          "answer",
          "sources",
          "knowledgeVersion",
          "needsHuman"
        ],
        "additionalProperties": false
      },
      "AISupportAnswer": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "const": "ai"
          },
          "answer": {
            "type": "string",
            "minLength": 1,
            "maxLength": 6000,
            "description": "Nur Klartext; URLs und HTML werden abgelehnt. Links werden nur in Quellen zurückgegeben."
          },
          "sources": {
            "type": "array",
            "maxItems": 25,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/SupportSource"
            }
          },
          "knowledgeVersion": {
            "type": "string"
          },
          "needsHuman": {
            "type": "boolean"
          }
        },
        "required": [
          "mode",
          "answer",
          "sources",
          "knowledgeVersion",
          "needsHuman"
        ],
        "additionalProperties": false,
        "allOf": [
          {
            "if": {
              "properties": {
                "needsHuman": {
                  "const": false
                }
              }
            },
            "then": {
              "properties": {
                "sources": {
                  "minItems": 1
                }
              }
            }
          }
        ]
      },
      "SupportAnswer": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/SearchSupportAnswer"
          },
          {
            "$ref": "#/components/schemas/AISupportAnswer"
          }
        ]
      },
      "Ticket": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^tkt_[a-f0-9-]{36}$"
          },
          "subject": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "answered",
              "closed"
            ],
            "description": "answered kennzeichnet eine beantwortete Anfrage. Die öffentliche API erlaubt einem Benutzer, nur seine eigene Anfrage zu schließen."
          },
          "source": {
            "type": "string",
            "enum": [
              "web",
              "telegram"
            ]
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "id",
          "subject",
          "message",
          "status",
          "source",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "TicketResponse": {
        "type": "object",
        "properties": {
          "ticket": {
            "$ref": "#/components/schemas/Ticket"
          }
        },
        "required": [
          "ticket"
        ],
        "additionalProperties": false
      },
      "Notification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^ntf_[A-Za-z0-9-]{1,80}$"
          },
          "kind": {
            "type": "string",
            "enum": [
              "payments",
              "payouts",
              "support",
              "security",
              "test"
            ]
          },
          "message": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "sending",
              "sent",
              "failed"
            ],
            "description": "Telegram-Zustellstatus, unabhängig vom Web-Lesestatus."
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "sentAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "readAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Zeitpunkt des ersten Lesens auf der Website; null bedeutet ungelesen. Dies bestätigt nicht, dass es in Telegram gelesen wurde."
          }
        },
        "required": [
          "id",
          "kind",
          "message",
          "status",
          "createdAt",
          "sentAt",
          "readAt"
        ],
        "additionalProperties": false
      },
      "NotificationsPage": {
        "type": "object",
        "properties": {
          "notifications": {
            "type": "array",
            "maxItems": 30,
            "items": {
              "$ref": "#/components/schemas/Notification"
            }
          },
          "unreadCount": {
            "type": "integer",
            "minimum": 0
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cursor für die nächste Seite; null, wenn keine weiteren Datensätze vorhanden sind."
          }
        },
        "required": [
          "notifications",
          "unreadCount",
          "nextCursor"
        ],
        "additionalProperties": false
      },
      "ReadNotifications": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "ids": {
                "type": "array",
                "minItems": 1,
                "maxItems": 100,
                "description": "Duplikate sind erlaubt und werden einmal gezählt.",
                "items": {
                  "type": "string",
                  "pattern": "^ntf_[A-Za-z0-9-]{1,80}$"
                }
              }
            },
            "required": [
              "ids"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "all": {
                "type": "boolean",
                "const": true
              },
              "before": {
                "type": "integer",
                "minimum": 0,
                "description": "createdAt des zuletzt angezeigten Ereignisses. Der Server verlangt außerdem before <= Date.now().",
                "maximum": 9007199254740991
              }
            },
            "required": [
              "all",
              "before"
            ],
            "additionalProperties": false
          }
        ]
      },
      "ReadNotificationsResult": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer",
            "minimum": 0
          },
          "readAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "unreadCount": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "updated",
          "readAt",
          "unreadCount"
        ],
        "additionalProperties": false
      },
      "TelegramUpdate": {
        "type": "object",
        "properties": {
          "update_id": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "message": {
            "type": "object",
            "additionalProperties": true,
            "description": "Telegram-Nachricht: der Handler verwendet message_id, text, from und chat."
          },
          "callback_query": {
            "type": "object",
            "additionalProperties": true,
            "description": "Telegram CallbackQuery: der Handler verwendet id, from, data und message.chat."
          }
        },
        "required": [
          "update_id"
        ],
        "additionalProperties": true
      },
      "IncomingQuote": {
        "type": "object",
        "properties": {
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "baseMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "grossMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "percentageFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "fixedFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "nominalFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "feeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "vatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "customerVatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantVatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "customerTotalMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantDeductionMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "totalFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "netMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "method": {
            "type": "string",
            "enum": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ]
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant",
              "shared"
            ]
          },
          "vatApplies": {
            "type": "boolean"
          },
          "pricingVersion": {
            "type": "integer",
            "minimum": 1,
            "description": "Berechnungsversion, mit der Rechnung gespeichert."
          },
          "vatCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
          },
          "feeCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
            "default": 0
          },
          "customerFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "settlement": {
            "$ref": "#/components/schemas/SettlementQuote"
          }
        },
        "required": [
          "amountMinor",
          "baseMinor",
          "grossMinor",
          "percentageFeeMinor",
          "fixedFeeMinor",
          "nominalFeeMinor",
          "feeMinor",
          "vatMinor",
          "customerVatMinor",
          "merchantVatMinor",
          "customerTotalMinor",
          "merchantDeductionMinor",
          "totalFeeMinor",
          "netMinor",
          "currency",
          "method",
          "vatPayer",
          "vatApplies",
          "pricingVersion"
        ],
        "additionalProperties": false
      },
      "PaymentLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^lnk_[0-9a-f-]{36}$"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "merchantName": {
            "type": "string"
          },
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant",
              "shared"
            ]
          },
          "methods": {
            "type": "array",
            "minItems": 1,
            "maxItems": 3,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "card",
                "alipay",
                "sbp",
                "crypto"
              ]
            }
          },
          "quotes": {
            "type": "object",
            "properties": {
              "card": {
                "$ref": "#/components/schemas/IncomingQuote"
              },
              "alipay": {
                "$ref": "#/components/schemas/IncomingQuote"
              },
              "sbp": {
                "$ref": "#/components/schemas/IncomingQuote"
              },
              "crypto": {
                "$ref": "#/components/schemas/IncomingQuote"
              }
            },
            "required": [],
            "additionalProperties": false
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "expired",
              "cancelled"
            ],
            "description": "abgelaufen wird beim Lesen aus expiresAt abgeleitet. storniert ist endgültig."
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Öffentliche /pay/{token}-Seite auf APP_ORIGIN."
          },
          "vatCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
          },
          "feeCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
            "default": 0
          },
          "orderId": {
            "type": "string",
            "maxLength": 100,
            "description": "Für den Käufer sichtbare Bestellreferenz."
          },
          "metadata": {
            "type": "object",
            "maxProperties": 10,
            "propertyNames": {
              "pattern": "^[A-Za-z0-9_-]{1,40}$"
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "description": "Private Händler-Metadaten. Höchstens 3000 UTF-8-Bytes nach JSON-Serialisierung. Wird im öffentlichen Checkout nie offengelegt."
          },
          "checkoutUrl": {
            "type": "string",
            "format": "uri"
          },
          "payment": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PaymentSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "In GET-Anfragen für Besitzerliste/-details enthalten. Der Rechnungslebenszyklus ist unabhängig vom verifizierten Zahlungsstatus. Enthält keine Karten-, Bankcode-, QR- oder Käuferdetails."
          },
          "storeId": {
            "type": "string",
            "pattern": "^sto_[A-Za-z0-9_-]+$"
          },
          "pricingMode": {
            "type": "string",
            "enum": [
              "native",
              "universal"
            ]
          },
          "fx": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ExchangeRate"
              },
              {
                "type": "null"
              }
            ]
          },
          "usdtPerUsd": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "title",
          "description",
          "merchantName",
          "amountMinor",
          "currency",
          "vatPayer",
          "methods",
          "quotes",
          "status",
          "createdAt",
          "updatedAt",
          "expiresAt",
          "url",
          "vatCustomerPercent",
          "feeCustomerPercent",
          "orderId",
          "metadata",
          "checkoutUrl"
        ],
        "additionalProperties": false
      },
      "CreatePaymentLink": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "x-trimmedMaxLength": 120,
                "x-trimmedMinLength": 1,
                "description": "Umgebende Leerzeichen werden getrimmt. Länge nach dem Trimmen: 1–120 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
              },
              "description": {
                "type": "string",
                "x-trimmedMaxLength": 500,
                "description": "Optional; ein leerer String ist zulässig. Bis zu 500 Zeichen nach dem Kürzen."
              },
              "amountMinor": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10000000000,
                "description": "Technische Ganzzahlgrenze, keine kommerzielle Anbietergrenze. Ein negativer Händlerkredit wird abgelehnt."
              },
              "vatPayer": {
                "type": "string",
                "enum": [
                  "customer",
                  "merchant"
                ],
                "description": "Wenn weggelassen, wird die aktuelle Regel des Geschäfts gespeichert."
              },
              "expiresAt": {
                "type": "integer",
                "minimum": 0,
                "description": "Ein zukünftiger Zeitpunkt, höchstens 90 Tage nach Erstellung. Standardmäßig sieben Tage. Im Rechnungsschnappschuss gespeichert."
              },
              "currency": {
                "type": "string",
                "const": "USD"
              },
              "methods": {
                "type": "array",
                "minItems": 1,
                "maxItems": 3,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "enum": [
                    "card",
                    "alipay",
                    "crypto"
                  ]
                },
                "description": "Neue USD-Checkouts unterstützen Karte und Alipay. USD-Krypto-Rechnungen werden nur aus Kompatibilitätsgründen akzeptiert und geben crypto_requires_usdt beim Live-Checkout zurück; verwenden Sie USDT für Krypto."
              },
              "vatCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
              },
              "feeCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
                "default": 0
              },
              "orderId": {
                "type": "string",
                "maxLength": 100,
                "description": "Für den Käufer sichtbare Bestellreferenz."
              },
              "metadata": {
                "type": "object",
                "maxProperties": 10,
                "propertyNames": {
                  "pattern": "^[A-Za-z0-9_-]{1,40}$"
                },
                "additionalProperties": {
                  "type": "string",
                  "maxLength": 500
                },
                "description": "Private Händler-Metadaten. Höchstens 3000 UTF-8-Bytes nach JSON-Serialisierung. Wird im öffentlichen Checkout nie offengelegt."
              },
              "pricingMode": {
                "type": "string",
                "const": "native",
                "description": "Legacy-währungsspezifische Preise. Weglassen für Kompatibilität mit bestehenden Integrationen."
              }
            },
            "required": [
              "title",
              "amountMinor",
              "currency",
              "methods"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "x-trimmedMaxLength": 120,
                "x-trimmedMinLength": 1,
                "description": "Umgebende Leerzeichen werden getrimmt. Länge nach dem Trimmen: 1–120 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
              },
              "description": {
                "type": "string",
                "x-trimmedMaxLength": 500,
                "description": "Optional; ein leerer String ist zulässig. Bis zu 500 Zeichen nach dem Kürzen."
              },
              "amountMinor": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10000000000,
                "description": "Technische Ganzzahlgrenze, keine kommerzielle Anbietergrenze. Ein negativer Händlerkredit wird abgelehnt."
              },
              "vatPayer": {
                "type": "string",
                "enum": [
                  "customer",
                  "merchant"
                ],
                "description": "Wenn weggelassen, wird die aktuelle Regel des Geschäfts gespeichert."
              },
              "expiresAt": {
                "type": "integer",
                "minimum": 0,
                "description": "Ein zukünftiger Zeitpunkt, höchstens 90 Tage nach Erstellung. Standardmäßig sieben Tage. Im Rechnungsschnappschuss gespeichert."
              },
              "currency": {
                "type": "string",
                "const": "RUB"
              },
              "methods": {
                "type": "array",
                "minItems": 1,
                "maxItems": 1,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "const": "sbp"
                }
              },
              "vatCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
              },
              "feeCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
                "default": 0
              },
              "orderId": {
                "type": "string",
                "maxLength": 100,
                "description": "Für den Käufer sichtbare Bestellreferenz."
              },
              "metadata": {
                "type": "object",
                "maxProperties": 10,
                "propertyNames": {
                  "pattern": "^[A-Za-z0-9_-]{1,40}$"
                },
                "additionalProperties": {
                  "type": "string",
                  "maxLength": 500
                },
                "description": "Private Händler-Metadaten. Höchstens 3000 UTF-8-Bytes nach JSON-Serialisierung. Wird im öffentlichen Checkout nie offengelegt."
              },
              "pricingMode": {
                "type": "string",
                "const": "native",
                "description": "Legacy-währungsspezifische Preise. Weglassen für Kompatibilität mit bestehenden Integrationen."
              }
            },
            "required": [
              "title",
              "amountMinor",
              "currency",
              "methods"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "x-trimmedMaxLength": 120,
                "x-trimmedMinLength": 1,
                "description": "Umgebende Leerzeichen werden getrimmt. Länge nach dem Trimmen: 1–120 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
              },
              "description": {
                "type": "string",
                "x-trimmedMaxLength": 500,
                "description": "Optional; ein leerer String ist zulässig. Bis zu 500 Zeichen nach dem Kürzen."
              },
              "amountMinor": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10000000000,
                "description": "Technische Ganzzahlgrenze, keine kommerzielle Anbietergrenze. Ein negativer Händlerkredit wird abgelehnt."
              },
              "vatPayer": {
                "type": "string",
                "enum": [
                  "customer",
                  "merchant"
                ],
                "description": "Wenn weggelassen, wird die aktuelle Regel des Geschäfts gespeichert."
              },
              "expiresAt": {
                "type": "integer",
                "minimum": 0,
                "description": "Ein zukünftiger Zeitpunkt, höchstens 90 Tage nach Erstellung. Standardmäßig sieben Tage. Im Rechnungsschnappschuss gespeichert."
              },
              "currency": {
                "type": "string",
                "const": "USDT"
              },
              "methods": {
                "type": "array",
                "minItems": 1,
                "maxItems": 1,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "const": "crypto"
                }
              },
              "vatCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
              },
              "feeCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
                "default": 0
              },
              "orderId": {
                "type": "string",
                "maxLength": 100,
                "description": "Für den Käufer sichtbare Bestellreferenz."
              },
              "metadata": {
                "type": "object",
                "maxProperties": 10,
                "propertyNames": {
                  "pattern": "^[A-Za-z0-9_-]{1,40}$"
                },
                "additionalProperties": {
                  "type": "string",
                  "maxLength": 500
                },
                "description": "Private Händler-Metadaten. Höchstens 3000 UTF-8-Bytes nach JSON-Serialisierung. Wird im öffentlichen Checkout nie offengelegt."
              },
              "pricingMode": {
                "type": "string",
                "const": "native",
                "description": "Legacy-währungsspezifische Preise. Weglassen für Kompatibilität mit bestehenden Integrationen."
              }
            },
            "required": [
              "title",
              "amountMinor",
              "currency",
              "methods"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "x-trimmedMaxLength": 120,
                "x-trimmedMinLength": 1,
                "description": "Umgebende Leerzeichen werden getrimmt. Länge nach dem Trimmen: 1–120 Zeichen. Steuerzeichen außer Tabs und Zeilenumbrüchen sind verboten."
              },
              "description": {
                "type": "string",
                "x-trimmedMaxLength": 500,
                "description": "Optional; ein leerer String ist zulässig. Bis zu 500 Zeichen nach dem Kürzen."
              },
              "amountMinor": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10000000000,
                "description": "Technische Ganzzahlgrenze, keine kommerzielle Anbietergrenze. Ein negativer Händlerkredit wird abgelehnt."
              },
              "vatPayer": {
                "type": "string",
                "enum": [
                  "customer",
                  "merchant"
                ],
                "description": "Wenn weggelassen, wird die aktuelle Regel des Geschäfts gespeichert."
              },
              "expiresAt": {
                "type": "integer",
                "minimum": 0,
                "description": "Ein zukünftiger Zeitpunkt, höchstens 90 Tage nach Erstellung. Standardmäßig sieben Tage. Im Rechnungsschnappschuss gespeichert."
              },
              "currency": {
                "type": "string",
                "enum": [
                  "USD",
                  "RUB",
                  "USDT"
                ],
                "description": "Eingabeeinheit. RUB wird zum gespeicherten Referenzkurs in USD umgerechnet; USDT verwendet die explizite 1:1-Rechnungsregel. Die gespeicherte Rechnungsbasiswährung ist USD."
              },
              "methods": {
                "type": "array",
                "minItems": 1,
                "maxItems": 4,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "enum": [
                    "card",
                    "alipay",
                    "sbp",
                    "crypto"
                  ]
                }
              },
              "vatCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
              },
              "feeCustomerPercent": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
                "default": 0
              },
              "orderId": {
                "type": "string",
                "maxLength": 100,
                "description": "Für den Käufer sichtbare Bestellreferenz."
              },
              "metadata": {
                "type": "object",
                "maxProperties": 10,
                "propertyNames": {
                  "pattern": "^[A-Za-z0-9_-]{1,40}$"
                },
                "additionalProperties": {
                  "type": "string",
                  "maxLength": 500
                },
                "description": "Private Händler-Metadaten. Höchstens 3000 UTF-8-Bytes nach JSON-Serialisierung. Wird im öffentlichen Checkout nie offengelegt."
              },
              "pricingMode": {
                "type": "string",
                "const": "universal"
              }
            },
            "required": [
              "title",
              "amountMinor",
              "currency",
              "methods",
              "pricingMode"
            ],
            "additionalProperties": false
          }
        ],
        "description": "Beträge verwenden Untereinheiten. Gebühr und MwSt werden auf den Basisbestellbetrag berechnet. Der Kundenanteil wird halb aufgerundet; der Händler übernimmt den genauen Restbetrag. Ein widersprüchlicher Legacy-vatPayer und vatCustomerPercent wird abgelehnt. Die Zuordnung ist nach der Erstellung unveränderlich; geben Sie eine neue Rechnung aus, um sie zu ändern. Live-Karte/Alipay erfordert vatCustomerPercent=100 und feeCustomerPercent=0, da das konfigurierte Gateway seine exklusive Steuer nicht überschreiben kann. Andere gespeicherte Zuordnungen geben unsupported_allocation zurück; sie werden nie stillschweigend geändert. SBP und USDT-Krypto unterstützen Gebührenzuordnung. Verwenden Sie das öffentliche Rechnungsverfügbarkeitsobjekt, bevor Sie Zahlungsdetails erfassen. Der universelle Modus speichert einen USD-Basispreis und separate native Belastungsangebote: USD für Karten/Alipay, RUB für SBP, USDT für Krypto. RUB-Umrechnung verwendet einen gespeicherten Referenzkurs der Bank von Russland. Krypto verwendet die explizite Rechnungsregel 1 USD = 1 USDT, keinen Marktkurs. Rechnungen mit RUB-Umrechnung sind auf 24 Stunden begrenzt, auch wenn expiresAt ein späteres Datum anfordert. Ein Fehler der FX-Quelle gibt 503 FX_UNAVAILABLE zurück. Lassen Sie pricingMode für Legacy-natives Verhalten weg.",
        "examples": [
          {
            "pricingMode": "universal",
            "title": "Bestellung 1042",
            "amountMinor": 1000,
            "currency": "USD",
            "methods": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ],
            "vatCustomerPercent": 100,
            "feeCustomerPercent": 0
          },
          {
            "title": "Bestellung 1042",
            "amountMinor": 500,
            "currency": "USD",
            "methods": [
              "card",
              "alipay"
            ],
            "vatCustomerPercent": 100,
            "feeCustomerPercent": 0,
            "orderId": "1042"
          },
          {
            "title": "Bestellung 1043",
            "amountMinor": 1000,
            "currency": "USDT",
            "methods": [
              "crypto"
            ],
            "feeCustomerPercent": 23,
            "orderId": "1043"
          }
        ]
      },
      "PaymentLinkResponse": {
        "type": "object",
        "properties": {
          "link": {
            "$ref": "#/components/schemas/PaymentLink"
          },
          "checkoutUrl": {
            "type": "string",
            "format": "uri",
            "description": "In Statusaktualisierungsantworten enthalten; der verschachtelte Link enthält immer seine checkoutUrl."
          }
        },
        "required": [
          "link"
        ],
        "additionalProperties": false
      },
      "CreatePaymentLinkResponse": {
        "type": "object",
        "properties": {
          "link": {
            "$ref": "#/components/schemas/PaymentLink"
          },
          "replayed": {
            "type": "boolean"
          },
          "checkoutUrl": {
            "type": "string",
            "format": "uri",
            "description": "Der Zahlungslink ist sofort verfügbar; kein Abfragen erforderlich."
          }
        },
        "required": [
          "link",
          "replayed",
          "checkoutUrl"
        ],
        "additionalProperties": false
      },
      "PaymentLinksPage": {
        "type": "object",
        "properties": {
          "links": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/PaymentLink"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Undurchsichtiger Cursor für die nächste Seite. Als URL-kodierten Abfrageparameter übergeben; null markiert das Ende."
          }
        },
        "required": [
          "links",
          "nextCursor"
        ],
        "additionalProperties": false
      },
      "CheckoutQuote": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ]
          },
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "vatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "customerVatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "customerTotalMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "vatApplies": {
            "type": "boolean"
          },
          "pricingVersion": {
            "type": "integer",
            "minimum": 1,
            "description": "Berechnungsversion, mit der Rechnung gespeichert."
          },
          "customerFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantCoveredMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          }
        },
        "required": [
          "method",
          "amountMinor",
          "vatMinor",
          "customerVatMinor",
          "customerTotalMinor",
          "vatApplies",
          "pricingVersion",
          "customerFeeMinor",
          "merchantCoveredMinor"
        ],
        "additionalProperties": false
      },
      "CheckoutInvoice": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "merchantName": {
            "type": "string"
          },
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant",
              "shared"
            ]
          },
          "methods": {
            "type": "array",
            "minItems": 1,
            "maxItems": 3,
            "items": {
              "type": "string",
              "enum": [
                "card",
                "alipay",
                "sbp",
                "crypto"
              ]
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "expired",
              "cancelled"
            ],
            "description": "abgelaufen wird beim Lesen aus expiresAt abgeleitet. storniert ist endgültig."
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "quote": {
            "$ref": "#/components/schemas/CheckoutQuote"
          },
          "gatewayConnected": {
            "type": "boolean",
            "description": "Kompatibilitätsalias für availability.available, kein Gateway-Gesundheitstest."
          },
          "vatCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
          },
          "feeCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
            "default": 0
          },
          "orderId": {
            "type": "string",
            "maxLength": 100,
            "description": "Für den Käufer sichtbare Bestellreferenz."
          },
          "availability": {
            "$ref": "#/components/schemas/CheckoutAvailability"
          },
          "baseAmountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "baseCurrency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ]
          },
          "fx": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ExchangeRate"
              },
              {
                "type": "null"
              }
            ]
          },
          "usdtPerUsd": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "token",
          "title",
          "description",
          "merchantName",
          "amountMinor",
          "currency",
          "vatPayer",
          "methods",
          "status",
          "expiresAt",
          "createdAt",
          "quote",
          "gatewayConnected",
          "vatCustomerPercent",
          "feeCustomerPercent",
          "orderId",
          "availability"
        ],
        "additionalProperties": false
      },
      "MerchantKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^key_[0-9a-f-]{36}$"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 3,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "invoices:read",
                "invoices:write",
                "events:read"
              ]
            }
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "revokedAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "lastUsedAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "storeId": {
            "type": "string",
            "pattern": "^sto_[A-Za-z0-9_-]+$"
          }
        },
        "required": [
          "id",
          "name",
          "prefix",
          "scopes",
          "createdAt",
          "expiresAt"
        ],
        "additionalProperties": false
      },
      "MerchantEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^evt_[a-f0-9]{40}$"
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice.created",
              "invoice.updated",
              "payment.succeeded",
              "payment.failed",
              "payment.refunded",
              "payment.partially_refunded",
              "payment.disputed",
              "payment.review_required"
            ]
          },
          "apiVersion": {
            "type": "string",
            "const": "2026-10-21"
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "livemode": {
            "type": "boolean"
          },
          "data": {
            "type": "object",
            "additionalProperties": true,
            "description": "invoice.created/updated: gespeicherte Händlerrechnung, einschließlich privater Metadaten. payment-Ereignisse: verifizierte Zahlungsfakten. Siehe Webhook-Leitfaden für Beispiele."
          }
        },
        "required": [
          "id",
          "type",
          "apiVersion",
          "createdAt",
          "livemode",
          "data"
        ],
        "additionalProperties": false
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^wh_[0-9a-f-]{36}$"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "invoice.created",
                "invoice.updated",
                "payment.succeeded",
                "payment.failed",
                "payment.refunded",
                "payment.partially_refunded",
                "payment.disputed",
                "payment.review_required"
              ]
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "unverified",
              "active",
              "paused"
            ]
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "verifiedAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "storeId": {
            "type": "string",
            "pattern": "^sto_[A-Za-z0-9_-]+$"
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "events",
          "status",
          "createdAt",
          "verifiedAt"
        ],
        "additionalProperties": false
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "event_id": {
            "type": "string"
          },
          "endpoint_id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice.created",
              "invoice.updated",
              "payment.succeeded",
              "payment.failed",
              "payment.refunded",
              "payment.partially_refunded",
              "payment.disputed",
              "payment.review_required"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "sending",
              "delivered",
              "failed",
              "cancelled"
            ]
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6
          },
          "next_attempt_at": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "last_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "delivered_at": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "id",
          "event_id",
          "endpoint_id",
          "type",
          "status",
          "attempts"
        ],
        "additionalProperties": false
      },
      "Application": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^app_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
          },
          "websiteUrl": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048
          },
          "businessName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "businessType": {
            "type": "string",
            "enum": [
              "digital_goods",
              "software",
              "services",
              "physical_goods",
              "education",
              "other"
            ]
          },
          "description": {
            "type": "string",
            "minLength": 40,
            "maxLength": 3000
          },
          "contactTelegram": {
            "type": "string",
            "pattern": "^@[A-Za-z][A-Za-z0-9_]{4,31}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "needs_review",
              "approved",
              "rejected"
            ]
          },
          "currentStage": {
            "type": "string",
            "enum": [
              "received",
              "ai_review",
              "technical_review",
              "manual_review"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "reason": {
            "type": "string",
            "description": "Benutzerseitige Stufenmeldung oder vom Moderator bearbeiteter Ablehnungsgrund. Interne Beweise sind ausgeschlossen."
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "stages": {
            "type": "array",
            "minItems": 4,
            "maxItems": 4,
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "enum": [
                    "received",
                    "ai_review",
                    "technical_review",
                    "manual_review"
                  ]
                },
                "state": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "running",
                    "complete",
                    "review",
                    "rejected"
                  ]
                },
                "message": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "minimum": 0,
                  "description": "Unix-Zeitstempel in Millisekunden, UTC."
                }
              },
              "required": [
                "id",
                "state",
                "message",
                "updatedAt"
              ],
              "additionalProperties": false
            }
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Private Tracking-URL mit expliziter Locale. Die Kenntnis der URL gewährt keinen Zugriff."
          },
          "notificationCategory": {
            "type": "string",
            "const": "support"
          },
          "canResume": {
            "type": "boolean"
          },
          "storeId": {
            "type": "string",
            "pattern": "^sto_[A-Za-z0-9_-]+$"
          }
        },
        "required": [
          "id",
          "websiteUrl",
          "businessName",
          "businessType",
          "description",
          "contactTelegram",
          "status",
          "currentStage",
          "version",
          "reason",
          "createdAt",
          "updatedAt",
          "stages",
          "url",
          "notificationCategory",
          "canResume"
        ],
        "additionalProperties": false
      },
      "ApplicationEvent": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "stage": {
            "type": "string",
            "enum": [
              "received",
              "ai_review",
              "technical_review",
              "manual_review"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "complete",
              "review",
              "rejected"
            ]
          },
          "message": {
            "type": "string"
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "version",
          "stage",
          "state",
          "message",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "PaymentSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Kanonische Gateway-Zahlungs-ID, falls bekannt; andernfalls die lokale gwp_-Vorgangs-ID."
          },
          "method": {
            "type": "string",
            "enum": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "requires_action",
              "processing",
              "succeeded",
              "failed",
              "expired",
              "review_required",
              "partially_paid",
              "partially_refunded",
              "refunded",
              "disputed"
            ]
          },
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "fulfillmentReady": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "refundedAmountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          }
        },
        "required": [
          "id",
          "method",
          "status",
          "amountMinor",
          "currency",
          "fulfillmentReady",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "CheckoutAvailability": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean"
          },
          "code": {
            "type": "string",
            "enum": [
              "ready",
              "not_configured",
              "unsupported_allocation",
              "crypto_requires_usdt",
              "amount_out_of_range",
              "merchant_not_approved"
            ]
          },
          "flow": {
            "type": "string",
            "enum": [
              "encrypted_card",
              "qr",
              "crypto"
            ]
          },
          "minAmountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "maxAmountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "limitsSource": {
            "type": "string",
            "const": "adapter",
            "description": "Konservative Grenzen, die von dieser Integration durchgesetzt werden, keine Aussage über die kommerziellen Grenzen des Anbieters."
          }
        },
        "required": [
          "available",
          "code",
          "flow",
          "minAmountMinor",
          "maxAmountMinor",
          "limitsSource"
        ],
        "additionalProperties": false
      },
      "CheckoutAction": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "redirect",
              "qr",
              "crypto"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "qrImage": {
            "type": [
              "string",
              "null"
            ]
          },
          "qrPayload": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": "string"
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
            "description": "Exakter Überweisungsbetrag in der gewählten Münze; die Dezimalzeichenfolge ohne Runden oder Gleitkomma-Umwandlung beibehalten."
          },
          "currency": {
            "type": "string"
          },
          "network": {
            "type": "string"
          },
          "networkLabel": {
            "type": "string"
          },
          "expiresAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "addressQrImage": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountQrImage": {
            "type": [
              "string",
              "null"
            ]
          },
          "amountQrPayload": {
            "type": [
              "string",
              "null"
            ]
          },
          "networkFeePaidByCustomer": {
            "type": "boolean"
          }
        },
        "required": [
          "type",
          "expiresAt"
        ],
        "additionalProperties": false
      },
      "CheckoutPayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^gwp_[0-9a-f-]{36}$"
          },
          "method": {
            "type": "string",
            "enum": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "requires_action",
              "processing",
              "succeeded",
              "failed",
              "expired",
              "review_required",
              "partially_paid",
              "partially_refunded",
              "refunded",
              "disputed"
            ]
          },
          "providerStatus": {
            "type": "string"
          },
          "fulfillmentReady": {
            "type": "boolean",
            "description": "Nur wahr nach exakter Betrags-/Währungs-/Bestellbindung und anbieterbestätigtem Erfolg. Eine Browser-Weiterleitung ist keine Zahlungsbestätigung."
          },
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "nextAction": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CheckoutAction"
              },
              {
                "type": "null"
              }
            ]
          },
          "expiresAt": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "authentication": {
            "type": "object",
            "properties": {
              "required": {
                "type": "boolean"
              },
              "expiresAt": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "description": "Unix-Zeitstempel in Millisekunden, UTC."
              },
              "attempt": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "required",
              "expiresAt",
              "attempt"
            ],
            "additionalProperties": false
          },
          "reason": {
            "type": "string",
            "enum": [
              "amount_mismatch",
              "confirmation_required",
              "refund_mismatch",
              "settlement_unverified"
            ]
          },
          "refundedAmountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          }
        },
        "required": [
          "id",
          "method",
          "status",
          "providerStatus",
          "fulfillmentReady",
          "amountMinor",
          "currency",
          "createdAt",
          "updatedAt",
          "nextAction",
          "expiresAt"
        ],
        "additionalProperties": false
      },
      "SealedCardData": {
        "type": "object",
        "properties": {
          "intent": {
            "type": "string",
            "minLength": 32,
            "maxLength": 8192,
            "description": "Signierte, kurzlebige Vorgangsabsicht von /card-intent; unverändert weiterleiten."
          },
          "jwe": {
            "type": "string",
            "maxLength": 14000,
            "pattern": "^[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+){4}$",
            "description": "Kompaktes JWE mit RSA-OAEP-256 und A256GCM. Geschützter Header: kid vom öffentlichen Schlüssel, typ=kevmi-card+jwe. Nur Chiffretext wird an Kevmi gesendet. Senden Sie niemals Klartext-Karten- oder Bankcode-Felder."
          }
        },
        "required": [
          "intent",
          "jwe"
        ],
        "additionalProperties": false
      },
      "CardIntent": {
        "type": "object",
        "properties": {
          "intent": {
            "type": "string",
            "minLength": 32,
            "maxLength": 8192
          },
          "intentId": {
            "type": "string",
            "maxLength": 100
          },
          "expiresAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "key": {
            "type": "object",
            "properties": {
              "kid": {
                "type": "string"
              },
              "kty": {
                "type": "string",
                "const": "RSA"
              },
              "n": {
                "type": "string"
              },
              "e": {
                "type": "string"
              },
              "alg": {
                "type": "string",
                "const": "RSA-OAEP-256"
              },
              "use": {
                "type": "string",
                "const": "enc"
              }
            },
            "required": [
              "kid",
              "kty",
              "n",
              "e",
              "alg",
              "use"
            ],
            "additionalProperties": false
          },
          "algorithm": {
            "type": "string",
            "const": "RSA-OAEP-256"
          },
          "encryption": {
            "type": "string",
            "const": "A256GCM"
          },
          "protocol": {
            "type": "string",
            "const": "kevmi-card-v1"
          }
        },
        "required": [
          "intent",
          "intentId",
          "expiresAt",
          "key",
          "algorithm",
          "encryption",
          "protocol"
        ],
        "additionalProperties": false
      },
      "StartCheckoutPayment": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "const": "card"
              },
              "sealed": {
                "$ref": "#/components/schemas/SealedCardData"
              }
            },
            "required": [
              "method",
              "sealed"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "const": "alipay"
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "country": {
                "type": "string",
                "const": "CN"
              },
              "email": {
                "type": "string",
                "format": "email",
                "maxLength": 254
              }
            },
            "required": [
              "method",
              "name",
              "country"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "const": "sbp"
              }
            },
            "required": [
              "method"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "const": "crypto"
              },
              "payerCurrency": {
                "type": "string",
                "pattern": "^[A-Z0-9]{2,16}$"
              },
              "network": {
                "type": "string",
                "pattern": "^[a-z0-9_-]{2,32}$"
              }
            },
            "required": [
              "method",
              "payerCurrency",
              "network"
            ],
            "additionalProperties": false
          }
        ]
      },
      "LegacyGatewayEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "type": "string",
            "maxLength": 100,
            "pattern": "^[A-Za-z0-9_.:-]+$"
          },
          "paymentId": {
            "type": "string",
            "maxLength": 100,
            "pattern": "^[A-Za-z0-9_.:-]+$"
          },
          "invoiceId": {
            "type": "string",
            "pattern": "^lnk_[0-9a-f-]{36}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "succeeded",
              "failed",
              "refunded"
            ]
          },
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "method": {
            "type": "string",
            "enum": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ]
          },
          "occurredAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "eventId",
          "paymentId",
          "invoiceId",
          "status",
          "amountMinor",
          "currency",
          "method",
          "occurredAt"
        ],
        "additionalProperties": false
      },
      "NativeGatewayEvent": {
        "type": "object",
        "required": [
          "id",
          "api_version",
          "mode",
          "type",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "api_version": {
            "type": "string",
            "const": "3"
          },
          "mode": {
            "type": "string",
            "const": "live"
          },
          "type": {
            "type": "string",
            "pattern": "^[a-z_.]{1,80}$"
          },
          "data": {
            "type": "object",
            "required": [
              "id",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "version": {
                "type": "integer",
                "minimum": 0
              },
              "merchant_order_id": {
                "type": "string"
              }
            }
          }
        }
      },
      "Store": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^sto_[A-Za-z0-9_-]+$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant"
            ]
          },
          "createdAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "updatedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          }
        },
        "required": [
          "id",
          "name",
          "vatPayer",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "ExchangeRate": {
        "type": "object",
        "properties": {
          "rubPerUsdMicros": {
            "type": "integer",
            "minimum": 1000000
          },
          "effectiveAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "fetchedAt": {
            "type": "integer",
            "minimum": 0,
            "description": "Unix-Zeitstempel in Millisekunden, UTC."
          },
          "source": {
            "type": "string",
            "const": "https://www.cbr.ru/scripts/XML_daily.asp"
          },
          "usdtPerUsd": {
            "type": "string",
            "const": "1.00"
          }
        },
        "required": [
          "rubPerUsdMicros",
          "effectiveAt",
          "fetchedAt",
          "source",
          "usdtPerUsd"
        ],
        "additionalProperties": false
      },
      "SettlementQuote": {
        "type": "object",
        "properties": {
          "amountMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "baseMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "grossMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "percentageFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "fixedFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "nominalFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "feeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "vatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "customerVatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantVatMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "customerTotalMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantDeductionMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "totalFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "netMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USD",
              "RUB",
              "USDT"
            ],
            "description": "Rechnungseinheiten: US-Cent, RUB-Kopeken oder Hundertstel von USDT. Keine automatische Währungsumrechnung."
          },
          "method": {
            "type": "string",
            "enum": [
              "card",
              "alipay",
              "sbp",
              "crypto"
            ]
          },
          "vatPayer": {
            "type": "string",
            "enum": [
              "customer",
              "merchant",
              "shared"
            ]
          },
          "vatApplies": {
            "type": "boolean"
          },
          "pricingVersion": {
            "type": "integer",
            "minimum": 1,
            "description": "Berechnungsversion, mit der Rechnung gespeichert."
          },
          "vatCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles. Standard: die bisherige Mehrwertsteuer-Präferenz des Geschäfts."
          },
          "feeCustomerPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kundenanteil als ganze Prozentzahl. 0 bedeutet, der Händler übernimmt alles; 100 bedeutet, der Kunde übernimmt alles.",
            "default": 0
          },
          "customerFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          },
          "merchantFeeMinor": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Ganzzahliger Betrag in kleineren Währungseinheiten."
          }
        },
        "required": [
          "amountMinor",
          "baseMinor",
          "grossMinor",
          "percentageFeeMinor",
          "fixedFeeMinor",
          "nominalFeeMinor",
          "feeMinor",
          "vatMinor",
          "customerVatMinor",
          "merchantVatMinor",
          "customerTotalMinor",
          "merchantDeductionMinor",
          "totalFeeMinor",
          "netMinor",
          "currency",
          "method",
          "vatPayer",
          "vatApplies",
          "pricingVersion"
        ],
        "additionalProperties": false
      }
    }
  },
  "webhooks": {
    "merchantEvent": {
      "post": {
        "summary": "Verifizierte Zustellung an den Händlerserver",
        "description": "Nur an aktive, challenge-verifizierte Endpunkte zugestellt. Rohes JSON ist signiert; überprüfen Sie Zeitstempel und Signatur, bevor Sie parsen oder den Bestellstatus ändern. Geben Sie 2xx zurück, nachdem Sie das Ereignis dauerhaft akzeptiert haben. Speichern Sie Ereignis-IDs, um Duplikate zu behandeln. Netzwerkfehler, Zeitüberschreitungen und Nicht-2xx-Status lösen Wiederholungen aus.",
        "parameters": [
          {
            "name": "Kevmi-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Kevmi-Event-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Kevmi-Delivery-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON-Objekt. Maximal 16.384 Byte. Unbekannte Felder werden abgelehnt.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Vom Händlerserver dauerhaft akzeptiert."
          }
        }
      }
    }
  }
}
