← Meterdoor · Artikel · Stand Oktober 2026

x402-Antwort richtig aufbauen: die häufigsten Fehler

Der Server sendet 402, aber kein Agent zahlt. Meist liegt es an einem einzelnen Feld in der Zahlungsanforderung. Zehn Fehlerquellen, die unser Prüfer abfragt – abgeleitet aus der Spezifikation und aus Fehlern, die wir beim Bau unserer eigenen Middleware gemacht haben, für x402 Version 1 und 2.

Bei x402 antwortet ein Server auf eine unbezahlte Anfrage mit 402 Payment Required und beschreibt in der Antwort, was er verlangt: Netz, Token, Betrag, Empfänger. Der Client liest diese Anforderung, signiert eine passende USDC-Autorisierung und wiederholt die Anfrage. Der Client prüft dabei nicht, was gemeint war, sondern was dasteht. Ein Betrag im falschen Format oder ein falscher Token-Name führt nicht zu einer verständlichen Fehlermeldung, sondern dazu, dass nicht gezahlt wird oder die Signatur später abgelehnt wird.

Vorweg zu den Versionen: In Version 1 steht die Anforderung als JSON im Body [1]. In Version 2 steht sie Base64-kodiert im Header PAYMENT-REQUIRED; die Spezifikation nennt den Header den maßgeblichen Ort, der Body ist Sache des Servers [2][3]. Viele Server senden heute beides. So sieht eine korrekte Anforderung in Version 2 aus (dekodierter Header, Testnetz Base Sepolia, 0,01 USDC):

{
  "x402Version": 2,
  "error": "Payment required",
  "resource": { "url": "https://api.example.com/api/bericht",
                "mimeType": "application/json" },
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:84532",
    "amount": "10000",
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "payTo": "0xIhreEmpfangsadresse…",
    "maxTimeoutSeconds": 60,
    "extra": { "name": "USDC", "version": "2" }
  }]
}

1. Statt 402 kommt etwas anderes

Der häufigste Fall ist banal: Eine Anmeldeschicht, ein Proxy oder die Reihenfolge der Middleware sorgt dafür, dass der Client 401, 403, eine Weiterleitung auf eine Login-Seite oder sogar 200 mit Inhalt bekommt. Ohne 402 fängt kein x402-Client an zu zahlen. Prüfen Sie den Endpunkt so, wie ein fremder Client ihn sieht: ohne Cookies, ohne Token, mit curl -i.

2. Betrag als Dezimalzahl

amount (Version 2) und maxAmountRequired (Version 1) sind Text mit einer Ganzzahl in kleinsten Einheiten [1][3]. USDC hat sechs Nachkommastellen, also ist 0,01 USDC "10000". Falsch sind "0.01", 0.01 als Zahl und 10000 ohne Anführungszeichen. Ein Betrag von "0" ist ebenfalls ein Fehler.

3. Netzformat der falschen Version

Version 1 nennt das Netz mit Namen wie "base" oder "base-sepolia" [1]. Version 2 verlangt CAIP-2-Kennungen: "eip155:8453" für Base, "eip155:84532" für Base Sepolia [3]. Wer beim Umstieg auf Version 2 nur den Header ergänzt und die Einträge aus Version 1 kopiert, schickt "base-sepolia" in Version 2 – oder umgekehrt "eip155:84532" in Version 1. Beides passt zu keinem Client.

4. Token-Adresse passt nicht zum Netz

asset ist die Vertragsadresse von USDC auf genau diesem Netz. Auf Base ist das 0x8335…2913, auf Base Sepolia 0x036C…CF7e [6]. Ein typischer Fehler beim Wechsel ins Hauptnetz: Das Netz wird umgestellt, die Testnetz-Adresse bleibt stehen. Der Client signiert dann für einen Vertrag, den es im Netz nicht gibt oder der nicht USDC ist.

5. Falscher EIP-712-Name in extra

Für das Schema exact mit EIP-3009 braucht der Client den EIP-712-Namen und die Version des Token-Vertrags, sonst kann er nicht korrekt signieren [4][5]. Der Haken: Die Namen unterscheiden sich je Netz. Der USDC-Vertrag auf Base meldet "USD Coin", der auf Base Sepolia "USDC", beide mit Version "2" (eigene Abfrage von name() und version() an beiden Verträgen, 26.10.2026). Fast alle Beispiele in Dokumentationen stehen im Testnetz und zeigen "USDC". Wer das für das Hauptnetz übernimmt, bekommt Signaturen, die der Vertrag ablehnt – erst beim Abrechnen, nachdem der Client schon „bezahlt“ hat.

6. Empfänger ungültig oder Platzhalter

payTo muss eine Adresse mit 0x und 40 Hexzeichen sein. Typische Reste aus Vorlagen sind Platzhalter wie oben im Beispiel, gekürzte Adressen und die Nulladresse 0x000…000. Eine Zahlung an die Nulladresse wäre verloren. Steht der Empfänger in einer Umgebungsvariablen, prüfen Sie, dass sie auf dem Server wirklich gesetzt ist und nicht leer in die Antwort fließt.

7. maxTimeoutSeconds fehlt oder ist zu knapp

Das Feld ist Pflicht [1][3]. Ein sehr kleiner Wert (wenige Sekunden) lässt Zahlungen scheitern, die auf der Kette etwas länger brauchen. Die Beispiele der Spezifikation nutzen 60 Sekunden.

8. Header PAYMENT-REQUIRED fehlt, ist kein Base64 oder bleibt im Browser unsichtbar

Clients für Version 2 lesen die Anforderung aus dem Header [2]; mit @x402/fetch 2.28 haben wir das selbst im Testnetz nachvollzogen. Drei Varianten dieses Fehlers:

// vor der Bezahlschranke einhängen
app.use("/api", (req, res, next) => {
  res.set("Access-Control-Allow-Origin", "*");
  res.set("Access-Control-Allow-Headers", "Content-Type, PAYMENT-SIGNATURE, X-PAYMENT");
  res.set("Access-Control-Expose-Headers", "PAYMENT-REQUIRED, PAYMENT-RESPONSE, X-PAYMENT-RESPONSE");
  if (req.method === "OPTIONS") return res.sendStatus(204);
  next();
});

Ob Sie fremde Seiten überhaupt zulassen wollen, ist eine eigene Entscheidung; für Agenten, die nicht im Browser laufen, spielt CORS keine Rolle.

9. Version 1 und Version 2 verlangen Unterschiedliches

Wer beide Versionen anbietet, pflegt die Anforderung oft an zwei Stellen. Dann stimmt nach einer Preisänderung der Betrag nur noch in einer Version, oder der Header nennt eine andere Empfangsadresse als der Body. Erzeugen Sie beide aus derselben Konfiguration und vergleichen Sie Empfänger, Betrag, Token und Netz.

10. Ressource fehlt oder ist relativ

Version 1 verlangt resource in jedem Eintrag, Version 2 einmal resource.url [1][3]. In beiden Fällen ist das die absolute Adresse der Ressource. Ein relativer Pfad wie /api/bericht oder hinter einem Proxy die interne Adresse (http://localhost:3000/…) sind häufige Fehler.

Und noch: Testnetz im Produktivbetrieb

Kein Formatfehler, aber teuer: Der Endpunkt ist live, verlangt aber USDC auf Base Sepolia. Zahlungen klappen, nur haben sie keinen Wert. Wer vom Test ins Hauptnetz wechselt, ändert drei Dinge zusammen: network, asset und extra.name (siehe Fehler 4 und 5). Außerdem braucht das Hauptnetz einen anderen Facilitator: Der öffentliche unter x402.org/facilitator unterstützt nur Testnetze [8].

Was eine korrekte Antwort nicht garantiert

Eine fehlerfreie 402-Antwort heißt nur, dass ein Client zahlen kann. Ob Ihr Server die Zahlung richtig prüft, nur bei Erfolg abrechnet und bei Verbindungsabbrüchen nicht doppelt liefert, sieht man der Antwort nicht an. Dafür hilft nur ein echter Testlauf im Testnetz, zum Beispiel mit @x402/fetch und einer Test-Wallet. Weitere Schemata (etwa exact mit Permit2 oder andere Netze als Base) folgen eigenen Regeln [4].

Selbst prüfen

Die zehn Punkte prüft unser kostenloser x402-Prüfer: Adresse eingeben oder die Ausgabe von curl -i einfügen, das Ergebnis zeigt je Feld OK, Hinweis oder Fehler. Er läuft im Browser, zahlt nicht, verbindet keine Wallet und schickt Ihre Adresse nicht an uns. Im Detail prüft er USDC auf Base und Base Sepolia im Schema exact; die OPTIONS-Vorabanfrage und eine interne Adresse wie localhost in der Ressource erkennt er nicht, CORS nur beim direkten Abruf, und ein bestandener Test garantiert keine erfolgreiche Zahlung.

Wer die Anforderung nicht von Hand bauen will: Der Meterdoor-Kern erzeugt Version 1 und 2 aus einer Konfiguration und bedient am selben Endpunkt auch Menschen mit Euro per Stripe Checkout. Er ist Open Source (Apache 2.0), ein Prototyp und bisher nur im Testnetz und im Stripe-Testmodus erprobt. Quellcode auf GitHub · Zur Produktseite

Dieser Artikel ist allgemeine technische Information, keine Rechts- oder Steuerberatung.

Quellen (abgerufen 26.10.2026)

  1. x402-Spezifikation Version 1
  2. x402-Spezifikation: HTTP-Transport Version 2
  3. x402-Spezifikation Version 2
  4. x402-Spezifikation: Schema exact auf EVM
  5. EIP-3009: Transfer With Authorization
  6. Circle: USDC-Vertragsadressen
  7. MDN: Access-Control-Expose-Headers
  8. x402-foundation/x402: README @x402/express („The default https://x402.org/facilitator supports testnets only“)

Meterdoor ist kein offizielles Produkt von x402, Coinbase oder Stripe. x402, Stripe und Base sind Marken ihrer Inhaber.