{"content_id":"gyaevhk2bq","slug":"x402-payments-2026-v2-base-usdc-settlement-guide","locale":"de","schema_type":"HowTo","category":"tutorial","category_name":"Tutorial","title":"x402-Zahlungen 2026: v2 umsetzen und Abrechnung prüfen","summary":"In dieser Node.js-Praxisübung erweitern Sie eine API mit x402 v2 um Mikrozahlungen. Wählen Sie auf Base Sepolia Zahlungsbedingungen aus, fordern Sie Signaturen erneut an und prüfen Sie die Abrechnung. Prüfen Sie außerdem erneute Übertragungen und die Voraussetzungen für den Wechsel ins Mainnet.","sponsorship_disclosure":null,"affiliate_disclosure":null,"commerce_disclosure":null,"author":{"name":"injoys","url":"https://injoys.com/ko/about"},"key_points":["Bereiten Sie die Empfängeradresse und eine Wallet für Testzahlungen vor und installieren Sie das offizielle x402 SDK.","Binden Sie die Zahlungs-Middleware für Base Sepolia ein und prüfen Sie die 402-Antwort auf eine Anfrage ohne Zahlung.","Wählen Sie nur Zahlungsbedingungen aus, die den clientseitig erlaubten Werten für Chain, Token, Betrag und Empfänger entsprechen, und signieren Sie diese.","Rufen Sie anhand des Transaktionshashs aus der Abrechnungsantwort die USDC Transfer-Ereignisse ab.","Testen Sie das Blockieren bei Fehlern und die Wiederherstellung nach doppelten Anfragen, bevor Sie die Mainnet-Einstellungen prüfen."],"content_markdown":"x402-Zahlungen werden implementiert, indem die Zahlungsbedingungen in der 402-Antwort der API übermittelt werden. Bereiten Sie Node.js und eine Test-Wallet vor. Prüfen Sie zunächst Signaturen und Abwicklung für v2 auf Base Sepolia. Konfigurieren Sie die kostenpflichtige Antwort so, dass sie erst nach erfolgreicher Abwicklung ausgeliefert wird.\n\nDie Angaben zu Beträgen und Chains beruhen auf den als Quellen verlinkten offiziellen Dokumentationen von x402, Base und Circle.\n\n## Vorbereitung und Installation\n\nBereiten Sie eine Entwicklungsumgebung vor, in der Sie die API ändern können, sowie eine Test-Wallet. Das Beispiel basiert auf Node.js 22 und x402 SDK 2.28.0. Der Installationsaufbau folgt dem [offiziellen Verkäuferleitfaden](https://docs.x402.org/getting-started/quickstart-for-sellers).\n\n1. Halten Sie eine EVM-Wallet-Adresse für den Zahlungsempfang bereit.\n2. Bereiten Sie eine separate Test-Wallet für Zahlungen vor.\n3. Beschaffen Sie Base Sepolia Test-USDC für die Zahlungs-Wallet.\n4. Erstellen Sie das Übungsprojekt mit den folgenden Befehlen.\n5. Speichern Sie die nachfolgenden TypeScript-Dateien im selben Ordner.\n\n```bash\nmkdir x402-demo\ncd x402-demo\nnpm init -y\nnpm pkg set type=module\nnpm install --save-exact express@5.3.0 viem@2.57.12 @x402/core@2.28.0 @x402/express@2.28.0 @x402/evm@2.28.0 @x402/fetch@2.28.0\nnpm install --save-dev --save-exact typescript tsx @types/node @types/express\n```\n\nDer empfangende Server benötigt den privaten Schlüssel der Empfänger-Wallet nicht. Konfigurieren Sie den privaten Zahlungsschlüssel so, dass er nur vom Client-Prozess gelesen wird. Das Signaturverfahren der Wallet richtet sich nach dem [offiziellen Käuferleitfaden](https://docs.x402.org/getting-started/quickstart-for-buyers).\n\nDieses Beispiel wurde durch Typprüfung und einen simulierten Zahlungsablauf geprüft. Eine tatsächliche Überweisung im Testnetz wurde damit noch nicht abgeschlossen. Prüfen Sie die Onchain-Ergebnisse bei der unten beschriebenen Ausführung selbst.\n\n## Vergleich von x402 v1 und v2\n\nBei der Implementierung von v2 müssen Header und Felder im Body aufeinander abgestimmt sein. Wenn Sie nur die Header-Namen ändern, passt die Datenstruktur nicht. Die folgende Tabelle basiert auf dem [offiziellen Migrationsleitfaden](https://docs.x402.org/guides/migration-v1-to-v2).\n\n| Merkmal | v1 | v2 |\n|---|---|---|\n| Protokollversion | `x402Version: 1` | `x402Version: 2` |\n| Anfängliche Zahlungsbedingungen | JSON-Body der 402-Antwort | Antwortheader `PAYMENT-REQUIRED` |\n| Signierte Zahlungsdaten | Anfrageheader `X-PAYMENT` | Anfrageheader `PAYMENT-SIGNATURE` |\n| Abwicklungsergebnis | Antwortheader `X-PAYMENT-RESPONSE` | Antwortheader `PAYMENT-RESPONSE` |\n| Kennung für Base Mainnet | `base` | `eip155:8453` |\n| Kennung für Base Sepolia | `base-sepolia` | `eip155:84532` |\n| Betragsfeld der Zahlungsbedingungen | `maxAmountRequired` | `amount` |\n| Ressourcenbeschreibung | `resource` usw. innerhalb der Zahlungsbedingungen | `resource`-Objekt auf oberster Ebene |\n| Bedingungen in der Zahlungs-Payload | `scheme`, `network` usw. auf oberster Ebene | `accepted`-Objekt mit den ausgewählten Bedingungen |\n| Beispiel für ein TypeScript-Paket | `x402-express` | `@x402/express` |\n\nWo v1 die Zahlungsbedingungen übermittelt, ist in der [HTTP-v1-Spezifikation](https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md) festgelegt. Bei v2 ist der Header `PAYMENT-REQUIRED` der standardmäßige Übermittlungsort. Eine Implementierung kann zusätzlich einen Body zurückgeben; richten Sie die Verarbeitung jedoch nach dem Header aus.\n\nDie [HTTP-v2-Spezifikation](https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md) beschreibt den Statuscode wie folgt.\n\n\u003e Der Server zeigt mit dem HTTP-Statuscode 402 „Payment Required“ an, dass eine Zahlung erforderlich ist.\n\u003e\n\u003e Quelle: x402 HTTP-v2-Spezifikation\n\nDie Zahlungsheader von v2 enthalten Base64-kodiertes JSON. Base64 ist kein Verschlüsselungsverfahren. Verwenden Sie HTTPS für extern zugängliche Dienste.\n\n## HTTP-402-Anfrage und Zahlungsablauf\n\nDiese Übung verwendet den grundlegenden Autorisierungsablauf des EVM-Verfahrens `exact`. Bei `exact` wird ein festgelegter Betrag bezahlt. Der Ablauf folgt der [Kernspezifikation von x402 v2](https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md).\n\n1. Der Client ruft die kostenpflichtige API ohne Zahlungsinformationen auf.\n2. Der Server gibt HTTP 402 und `PAYMENT-REQUIRED` zurück.\n3. Der Client wählt zulässige Bedingungen aus `accepts` aus.\n4. Das SDK signiert eine Zahlungsautorisierung für die ausgewählten Bedingungen.\n5. Der Client wiederholt die Anfrage mit `PAYMENT-SIGNATURE`.\n6. Der Server prüft die Autorisierung über `/verify` des Facilitators.\n7. Nach erfolgreicher Prüfung führt der Server die Ressourcenverarbeitung aus.\n8. Der Server fordert über `/settle` die Abwicklung an.\n9. Nach erfolgreicher Abwicklung liefert er den kostenpflichtigen Body und `PAYMENT-RESPONSE` aus.\n\nDiese Reihenfolge ist kein festgelegter Ablauf für alle Zahlungsverfahren. v2 definiert auch Abläufe mit einem anderen Abwicklungszeitpunkt. Der folgende Code lässt nur den grundlegenden Ablauf `authorization` zu.\n\n### Rollen von Ressourcenserver und Facilitator\n\nDer Ressourcenserver legt Preise und Zugangsbedingungen für Inhalte fest. Der Facilitator übernimmt die Zahlungsprüfung und Abwicklung. Die Rollenverteilung richtet sich nach der [offiziellen Facilitator-Dokumentation](https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md).\n\n| Komponente | Aufgabe | Zustand, der nicht als Erfolg gelten darf |\n|---|---|---|\n| Client | Bedingungen auswählen und Zahlungsautorisierung signieren | Nur die Signatur wurde erstellt |\n| Ressourcenserver | Preis angeben und kostenpflichtige Antworten steuern | Der Client behauptet, die Zahlung sei erfolgreich |\n| Facilitator `/verify` | Gültigkeit von Signatur und Zahlungsbedingungen prüfen | Es wurde lediglich `isValid: true` empfangen |\n| Facilitator `/settle` | In dieser Übung die Onchain-Zahlung ausführen und das Ergebnis zurückgeben | Die Transaktion wurde gesendet, das Ergebnis aber noch nicht bestätigt |\n\n`/verify` ist eine Prüfung, die den Onchain-Zustand nicht verändert. Eine erfolgreiche Prüfung bedeutet daher nicht, dass der Zahlungseingang abgeschlossen ist. Guthaben oder Autorisierungsstatus können sich auch nach der Prüfung noch ändern.\n\nSperren Sie den kostenpflichtigen Body, wenn Prüfung oder Abwicklung fehlschlagen. Ein Vorgehen, das den Zugriff sperrt, solange kein Erfolg bestätigt ist, wird als fail-closed bezeichnet. Dieses Verhalten lässt sich auch in der [offiziellen Express-Implementierung](https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts) nachvollziehen.\n\n## Vergleich von Base Mainnet und Testnetz\n\nVerwenden Sie beim ersten Durchlauf ausschließlich Base Sepolia. Circle stellt ausdrücklich fest, dass USDC im Testnetz keinen finanziellen Wert haben. Die Adressen stammen aus der [Liste der USDC-Contract-Adressen von Circle](https://developers.circle.com/stablecoins/usdc-contract-addresses).\n\n| Merkmal | Base Mainnet | Base Sepolia Testnetz |\n|---|---|---|\n| Zweck | Zahlungen mit realen Vermögenswerten | Implementierung und Fehlerbehandlung testen |\n| Chain ID | `8453` | `84532` |\n| Netzwerk für x402 v2 | `eip155:8453` | `eip155:84532` |\n| USDC-Contract | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | `0x036CbD53842c5426634e7929541eC2318f3dCF7e` |\n| Öffentlicher RPC | `https://mainnet.base.org` | `https://sepolia.base.org` |\n| Finanzieller Wert des Tokens | Vermögenswert mit realem finanziellem Wert | Kein finanzieller Wert |\n\nPrüfen Sie Chain ID und RPC in der [Base-Netzwerkdokumentation](https://docs.base.org/get-started/connect-to-base). Auch bei derselben Wallet-Adresse sind die Guthaben auf unterschiedlichen Chains getrennt. Ein Erfolg im Testnetz darf nicht als tatsächlicher Umsatz verbucht werden.\n\nTest-USDC können Sie beim [Circle Testnet Faucet](https://faucet.circle.com/) anfordern. Wählen Sie Base Sepolia als Netzwerk. Geben Sie als Empfängeradresse die Adresse der Test-Wallet für Zahlungen ein.\n\n## Kostenpflichtige API mit Node.js implementieren\n\nSchalten Sie `paymentMiddleware` vor die kostenpflichtige Route. Das folgende Beispiel verlangt **0.001 USDC** pro Aufruf. Der Betrag entspricht dem Beispielpreis aus dem offiziellen Verkäuferleitfaden. (Geprüfter Wert: 0.001 USDC pro Aufruf · Quelle: docs.x402.org · geprüft am 2026-10-28)\n\n### Serverdatei\n\nSpeichern Sie den folgenden Code als `server.ts`. Der Server nimmt Anfragen nur über die lokale Schnittstelle an. Die Empfängeradresse wird aus der Umgebungsvariablen `PAY_TO` gelesen.\n\n```typescript\nimport express from \"express\";\nimport { getAddress, zeroAddress } from \"viem\";\nimport { paymentMiddleware } from \"@x402/express\";\nimport { HTTPFacilitatorClient, x402ResourceServer } from \"@x402/core/server\";\nimport { ExactEvmScheme } from \"@x402/evm/exact/server\";\n\nconst payTo = getAddress(process.env.PAY_TO ?? \"\");\nif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\nconst network = \"eip155:84532\";\nconst resourceServer = new x402ResourceServer(\n  new HTTPFacilitatorClient({ url: \"https://x402.org/facilitator\" }),\n).register(network, new ExactEvmScheme());\n\nconst app = express();\napp.use((_req, res, next) =\u003e {\n  res.setHeader(\"Cache-Control\", \"private, no-store\");\n  next();\n});\napp.use(paymentMiddleware({\n  \"GET /paid-data\": {\n    accepts: [{ scheme: \"exact\", price: \"$0.001\", network, payTo }],\n    description: \"Sample paid JSON\",\n    mimeType: \"application/json\",\n  },\n}, resourceServer));\napp.get(\"/paid-data\", (_req, res) =\u003e {\n  res.json({ content: \"Paid sample content\" });\n});\napp.listen(4021, \"127.0.0.1\");\n```\n\n`https://x402.org/facilitator` ist die Testadresse aus dem offiziellen Leitfaden. In diesem Beispiel wird sie für die Abwicklung auf Base Sepolia verwendet. Informationen zur Auswahl eines Facilitators für den Produktivbetrieb finden Sie im [Mainnet-Verfahren des Verkäuferleitfadens](https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet).\n\n### Beispiel zur Preisberechnung\n\nDer Beispielpreis entspricht `1000` kleinsten USDC-Einheiten. USDC hat 6 Nachkommastellen. Die Preisumrechnung des SDK richtet sich nach der [EVM-Serverimplementierung](https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts).\n\n```text\n0.001 USDC × 10^6 = 1000 최소 단위\n```\n\n| Zu prüfender Wert | Erwarteter Wert in diesem Beispiel |\n|---|---|\n| `price` in der Serverkonfiguration | `\"$0.001\"` |\n| `amount` in den Zahlungsbedingungen der 402-Antwort | `\"1000\"` |\n| `asset` in den Zahlungsbedingungen | USDC-Contract auf Base Sepolia |\n| `payTo` in den Zahlungsbedingungen | Konfigurierte Empfängeradresse |\n| `network` in den Zahlungsbedingungen | `eip155:84532` |\n\n`price` ist ein Konfigurationswert des SDK. In den tatsächlichen Zahlungsbedingungen von v2 wird `amount` übermittelt. Vergleichen Sie ganzzahlige Beträge als Zeichenfolgen oder `bigint`.\n\n### Server starten und 402 prüfen\n\nStarten Sie den Server im ersten Bash-Terminal. Der eingegebene Wert ist die öffentliche Empfängeradresse, nicht der private Schlüssel. Lassen Sie dieses Terminal während der Ausführung geöffnet.\n\n```bash\nread -r -p '수취 지갑 주소: ' PAY_TO\nexport PAY_TO\nnpx tsx server.ts\n```\n\nSenden Sie aus einem zweiten Terminal eine Anfrage ohne Zahlung. Der folgende Befehl signiert keine Zahlung. Er gibt den HTTP-Status und die dekodierten Zahlungsbedingungen aus.\n\n```bash\nnode --input-type=module \u003c\u003c'JS'\nconst response = await fetch(\"http://127.0.0.1:4021/paid-data\");\nconst header = response.headers.get(\"PAYMENT-REQUIRED\");\nconsole.log(response.status);\nconsole.log(header \u0026\u0026 JSON.parse(\n  Buffer.from(header, \"base64\").toString(\"utf8\")\n));\nJS\n```\n\nDie reguläre Antwort ohne Zahlung ist HTTP 402. Vergleichen Sie die ausgegebenen Bedingungen mit der obigen Tabelle. Falls die kostenpflichtigen Inhalte direkt zurückgegeben werden, korrigieren Sie zuerst den Schutz der Route.\n\n## Zahlungsbedingungen auswählen und Client implementieren\n\nBeschränken Sie den Client darauf, nur erlaubte Bedingungen zu signieren. Dieses Beispiel erlaubt ausschließlich den festgelegten Preis in USDC auf Base Sepolia. Der Filter für Zahlungsoptionen verwendet `registerPolicy` aus der [offiziellen x402Client-Implementierung](https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts).\n\n1. Speichern Sie den folgenden Code als `client.ts`.\n2. Speichern Sie auch `check-transfer.ts` aus dem nächsten Abschnitt.\n3. Fahren Sie erst mit der Ausführung fort, wenn beide Dateien vorliegen.\n\n```typescript\nimport { writeFile } from \"node:fs/promises\";\nimport { getAddress, zeroAddress, type Hex, type Hash } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { x402Client, wrapFetchWithPayment } from \"@x402/fetch\";\nimport { decodePaymentResponseHeader } from \"@x402/core/http\";\nimport { ExactEvmScheme } from \"@x402/evm/exact/client\";\nimport { checkTransfer } from \"./check-transfer.js\";\n\nconst key = process.env.EVM_PRIVATE_KEY ?? \"\";\nif (!/^0x[0-9a-fA-F]{64}$/.test(key)) throw new Error(\"Invalid test key\");\nconst signer = privateKeyToAccount(key as Hex);\nconst payTo = getAddress(process.env.PAY_TO ?? \"\");\nif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\nconst network = \"eip155:84532\";\nconst token = \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\";\nconst client = new x402Client().register(network, new ExactEvmScheme(signer));\nclient.registerPolicy((version, options) =\u003e version === 2\n  ? options.filter(r =\u003e\n      r.scheme === \"exact\" \u0026\u0026 r.network === network \u0026\u0026\n      r.asset.toLowerCase() === token.toLowerCase() \u0026\u0026\n      r.payTo.toLowerCase() === payTo.toLowerCase() \u0026\u0026 r.amount === \"1000\" \u0026\u0026\n      (!r.extra?.assetTransferMethod || r.extra.assetTransferMethod === \"eip3009\") \u0026\u0026\n      (!r.extra?.paymentFlow || r.extra.paymentFlow === \"authorization\"))\n  : []);\n\nconst paidFetch = wrapFetchWithPayment(fetch, client);\nconst response = await paidFetch(\"http://127.0.0.1:4021/paid-data\", {\n  redirect: \"error\",\n});\nconst raw = response.headers.get(\"PAYMENT-RESPONSE\");\nif (!raw) throw new Error(`No settlement receipt: HTTP ${response.status}`);\nconst settlement = decodePaymentResponseHeader(raw);\nawait writeFile(\"settlement.json\", JSON.stringify(settlement, null, 2));\nif (!response.ok || !settlement.success || settlement.network !== network) {\n  throw new Error(\"Payment unresolved; inspect settlement.json before retrying\");\n}\nconst evidence = await checkTransfer(\n  network, settlement.transaction as Hash, signer.address, payTo, 1000n,\n);\nawait writeFile(\"transfer.json\", JSON.stringify(evidence, null, 2));\nconsole.log(await response.text());\n```\n\n`wrapFetchWithPayment` übernimmt die Verarbeitung von 402 und die erneute Anfrage mit Signatur. Die Verwendung folgt dem [offiziellen fetch-Beispiel](https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch). Wenn keine erlaubten Zahlungsbedingungen vorliegen, wird die Erstellung der Zahlung abgebrochen.\n\nDieser Client kann auch in KI-Agenten verwendet werden. Eine Preisgrenze pro Aufruf ist jedoch keine Grenze für die Gesamtausgaben. Verwalten Sie das Budget für wiederholte Aufrufe des Agenten separat.\n\n## USDC-Transfer-Ereignisse prüfen\n\nPrüfen Sie die USDC-Transfer-Logs anhand des Transaktionshashs aus dem Abwicklungsergebnis. Ein erfolgreicher Transaktionsstatus allein bestätigt noch nicht den Empfänger. Die Felder von `Transfer` richten sich nach dem [ERC-20-Standard](https://eips.ethereum.org/EIPS/eip-20).\n\nFür die Prüfung werden folgende Angaben benötigt.\n\n| Prüfpunkt | Vergleichswert |\n|---|---|\n| Chain ID des RPC | Vom Server zugelassene Chain |\n| `status` des Transaktionsbelegs | Erfolgsstatus |\n| Adresse, die das Ereignis ausgelöst hat | Offizieller USDC-Contract der betreffenden Chain |\n| `Transfer.from` | Bestätigter Zahler |\n| `Transfer.to` | Vom Server festgelegte Empfängeradresse |\n| `Transfer.value` | Vom Server verlangter Betrag in kleinsten Einheiten |\n\nSpeichern Sie den folgenden Code als `check-transfer.ts`. Die Abfrage verwendet [getTransactionReceipt](https://viem.sh/docs/actions/public/getTransactionReceipt) von viem. Die Auswertung der Ereignisse richtet sich nach [parseEventLogs](https://viem.sh/docs/contract/parseEventLogs).\n\n```typescript\nimport {\n  createPublicClient, http, getAddress, parseEventLogs,\n  erc20Abi, type Address, type Hash,\n} from \"viem\";\nimport { base, baseSepolia } from \"viem/chains\";\n\nconst configs = {\n  \"eip155:84532\": {\n    chain: baseSepolia,\n    rpc: \"https://sepolia.base.org\",\n    token: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n  },\n  \"eip155:8453\": {\n    chain: base,\n    rpc: \"https://mainnet.base.org\",\n    token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n  },\n} as const;\n\nexport async function checkTransfer(\n  network: keyof typeof configs, hash: Hash,\n  payer: Address, payTo: Address, amount: bigint,\n) {\n  const cfg = configs[network];\n  const rpc = createPublicClient({ chain: cfg.chain, transport: http(cfg.rpc) });\n  if (await rpc.getChainId() !== cfg.chain.id) throw new Error(\"Wrong chain\");\n  const receipt = await rpc.getTransactionReceipt({ hash });\n  if (receipt.status !== \"success\") throw new Error(\"Transaction failed\");\n  const logs = parseEventLogs({\n    abi: erc20Abi,\n    eventName: \"Transfer\",\n    logs: receipt.logs.filter(\n      log =\u003e getAddress(log.address) === getAddress(cfg.token),\n    ),\n    strict: true,\n  });\n  const transfer = logs.find(log =\u003e\n    getAddress(log.args.from) === getAddress(payer) \u0026\u0026\n    getAddress(log.args.to) === getAddress(payTo) \u0026\u0026\n    log.args.value === amount,\n  );\n  if (!transfer) throw new Error(\"Matching USDC Transfer not found\");\n  return {\n    network, transaction: hash, logIndex: transfer.logIndex,\n    blockHash: receipt.blockHash, blockNumber: receipt.blockNumber.toString(),\n  };\n}\n```\n\nDiese Funktion bestätigt den USDC-Transfer in der betreffenden Transaktion. Ob er einem bestimmten API-Auftrag zugeordnet ist, muss separat geprüft werden. Verwenden Sie auf einem Produktivserver die gespeicherten Auftragsbedingungen als Vergleichswerte.\n\nVertrauen Sie einer vom Client hochgeladenen Datei `transfer.json` nicht als Nachweis für die Zugangsberechtigung. Der Server dieses Beispiels verwendet die Prüf- und Abwicklungsergebnisse des Facilitators. Soll eine unabhängige Abfrage Voraussetzung für den Zugriff sein, muss sie auf dem Server ausgeführt werden.\n\nEine fehlgeschlagene Belegabfrage bedeutet nicht automatisch, dass die Zahlung fehlgeschlagen ist. Fragen Sie bei einem RPC-Fehler den gespeicherten Transaktionshash erneut ab. Die Anzahl zusätzlicher Bestätigungen und der Umgang mit Chain-Reorganisationen werden in den Betriebsrichtlinien festgelegt.\n\n## Testzahlung ausführen und Ergebnisse prüfen\n\nSpeichern Sie alle Dateien und führen Sie den Test mit der Test-Wallet aus. Die Typprüfung führt weder Signaturen noch Überweisungen aus. Der folgende Befehl verwendet die zuvor installierten TypeScript-Werkzeuge.\n\n1. Prüfen Sie die Typen mit dem folgenden Befehl.\n2. Geben Sie im zweiten Terminal dieselbe Empfängeradresse wie auf dem Server ein.\n3. Geben Sie den privaten Schlüssel der Test-Zahlungs-Wallet verdeckt ein.\n4. Führen Sie den Client einmal aus.\n5. Prüfen Sie das gespeicherte Abwicklungsergebnis und die Transfer-Logs.\n\n```bash\nnpx tsc --noEmit --strict --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext server.ts client.ts check-transfer.ts\nread -r -p '같은 수취 지갑 주소: ' PAY_TO\nread -r -s -p '테스트 결제 지갑 개인키: ' EVM_PRIVATE_KEY\nexport PAY_TO EVM_PRIVATE_KEY\nnpx tsx client.ts\nunset EVM_PRIVATE_KEY\n```\n\n| Ergebnis | Bedeutung | Zu prüfen |\n|---|---|---|\n| `settlement.json` | Vom Server zurückgegebenes Abwicklungsergebnis | `success`, `network`, `transaction` |\n| `transfer.json` | Bei der RPC-Abfrage gefundener Transferdatensatz | Chain, Transaktionshash, Log-Position, Blockinformationen |\n| Kostenpflichtiger Body in der Konsole | Daten, die nach der Prüfung durch diesen Client ausgegeben wurden | Prüfen, ob es sich um die angeforderten Inhalte handelt |\n\nEin erneuter Start des Clients kann eine neue Zahlung auslösen. Dieses Minimalbeispiel enthält keinen auftragsbezogenen Speicher zur Verhinderung von Duplikaten. Ergänzen Sie eine Wiederholungsfunktion erst, wenn die Voraussetzungen des nächsten Abschnitts erfüllt sind.\n\n## Behandlung verschiedener Prüfungsfehler\n\nPrüfen Sie bei Fehlertests, dass der kostenpflichtige Body nicht offengelegt wird. Wenn Sie nur den HTTP-Status prüfen, können Sie eine fehlende Zugriffssperre übersehen. Als Referenz für das Verhalten dient die [offizielle Express-Middleware](https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts).\n\n| Testbedingung | Erwartetes Verhalten | Zusätzliche Prüfung |\n|---|---|---|\n| Zahlungsheader fehlt | 402 und Zahlungsbedingungen zurückgeben | Kein kostenpflichtiger Body |\n| Anderer Token oder Empfänger angegeben | Durch Client-Richtlinie ablehnen | Keine Signatur erstellen |\n| Ungültige Signatur | Wegen fehlgeschlagener Prüfung sperren | Kostenpflichtigen Handler nicht ausführen |\n| Unzureichendes Guthaben | Wegen fehlgeschlagener Prüfung oder Abwicklung sperren | Nicht als erfolgreiche Abwicklung verbuchen |\n| Abwicklungsergebnis meldet Fehler | Kostenpflichtige Antwort sperren | Auch vorbereiteten Body nicht senden |\n| Verzögerte Antwort des Facilitators | Ohne Erfolgsbestätigung im ausstehenden Zustand halten | Keine neue Autorisierung automatisch erstellen |\n| RPC-Fehler bei der Belegabfrage | Transaktionshash speichern und erneut abfragen | Nicht vorschnell als Zahlungsfehler einstufen |\n\nIm grundlegenden Autorisierungsablauf wird der Handler vor der Abwicklung ausgeführt. Eine fehlgeschlagene Abwicklung macht externe Vorgänge nicht rückgängig. Beginnen Sie wie in diesem Beispiel mit Abfragen ohne Seiteneffekte.\n\nDer Versand von E-Mails oder das Anlegen externer Aufträge erfordert eine separate Konzeption. Speichern Sie Zahlungs- und Vorgangsstatus gemeinsam. Legen Sie fest, welche Schritte bei einem Fehler erneut ausgeführt werden, um doppelte Vorgänge zu reduzieren.\n\n## Wiederherstellung bei Antwortverlust nach der Abwicklung\n\nSpeichern Sie den Abschluss der Zahlung und den Abschluss der Inhaltsauslieferung als getrennte Zustände. Die Zahlung kann bereits abgeschlossen sein, während die Verbindung für die Antwort abbricht. Die Grundlage für den Umgang mit solchen Fällen bildet die [Dokumentation der Payment-Identifier-Erweiterung](https://docs.x402.org/extensions/payment-identifier).\n\nDie Eigenschaft, dass eine erneute Anfrage für denselben Vorgang nicht zu einer doppelten Verarbeitung führt, heißt Idempotenz. `payment-identifier` stellt dafür eine Zahlungskennung bereit. Diese Funktion ist nicht allein durch das Hinzufügen der Kennung vollständig umgesetzt.\n\n### Vergleich von Doppelzahlungen und erneuten Übertragungen\n\nDer Schutz vor Wiederverwendung derselben Signatur muss von der Verhinderung doppelter Aufträge unterschieden werden. EIP-3009 verhindert, dass ein bereits verwendeter Autorisierungs-Nonce erneut genutzt wird. Dieses Verhalten ist in der [ERC-3009-Spezifikation](https://eips.ethereum.org/EIPS/eip-3009) definiert.\n\n| Situation | Aus Sicht der Onchain-Autorisierung | Aus Sicht des API-Betriebs |\n|---|---|---|\n| Dieselbe Autorisierung erneut abwickeln | Prüfung auf bereits verwendeten Nonce | Bestehendes Ergebnis muss abgefragt werden |\n| Neue Autorisierung für denselben Auftrag erstellen | Kann als separate Autorisierung verarbeitet werden | Doppelzahlungen müssen verhindert werden |\n| Antwortverlust nach erfolgreicher Abwicklung | Vermögensübertragung kann abgeschlossen sein | Inhalte müssen erneut ausgeliefert werden |\n| Zeitüberschreitung nach Abwicklungsanfrage | Ergebnis ist noch unklar | Ausstehender Zustand und Prüfung der Abwicklung erforderlich |\n\nDas folgende Verfahren ist ein Entwurf zur Anbindung der offiziellen Erweiterung an einen Datenspeicher im Produktivbetrieb. Es ist im obigen Minimalcode nicht enthalten. Ergänzen Sie für den Produktivbetrieb einen persistenten Speicher und eine Steuerung gleichzeitiger Anfragen.\n\n1. Deklarieren Sie auf dem Server die Unterstützung der Erweiterung `payment-identifier`.\n2. Bewahren Sie auf dem Client die Kennung der logischen Anfrage auf.\n3. Verknüpfen Sie die Kennung auf dem Server mit dem Zahler und dem Anfrageinhalt.\n4. Speichern Sie den Bearbeitungsstatus atomar, um eine gleichzeitige Ausführung zu verhindern.\n5. Speichern Sie nach erfolgreicher Abwicklung den Transaktionsnachweis und das Antwortergebnis.\n6. Geben Sie bei einer erneuten Anfrage mit denselben Berechtigungen und Inhalten das gespeicherte Ergebnis zurück.\n7. Prüfen Sie bei unklarem Abwicklungsergebnis zuerst die bestehende Autorisierung.\n\nEine Zahlungskennung ist weder ein Passwort noch ein Zugriffstoken. Geben Sie kostenpflichtige Cache-Inhalte nicht an eine Anfrage zurück, die lediglich die Kennung kennt. Prüfen Sie auch, ob sie von einem anderen Nutzer oder mit einem anderen Anfrage-Body wiederverwendet wird.\n\nHalten Sie in den Betriebsaufzeichnungen Chain, Transaktionshash und Log-Position gemeinsam fest. Verknüpfen Sie diesen Datensatz mit dem Auftrag, um eine Wiederverwendung für andere Aufträge zu verhindern. Eine Übereinstimmung bei `Transfer` allein weist noch keine Auftragszuordnung nach.\n\n## Häufige Fehler bei der Zahlungsimplementierung\n\nWer Versionsfelder und Erfolgssignale verwechselt, kann den Zahlungsstatus falsch beurteilen. Nutzen Sie die folgende Tabelle für die Prüfung vor der Bereitstellung. Die Versionsunterschiede richten sich nach dem [x402-Migrationsleitfaden](https://docs.x402.org/guides/migration-v1-to-v2).\n\n| Häufiger Fehler | Korrekte Vorgehensweise |\n|---|---|\n| `extra.version: \"2\"` als x402-Version interpretieren | Protokollversion anhand von `x402Version` prüfen |\n| `maxAmountRequired` in v2 verwenden | Für den Betrag in den Zahlungsbedingungen `amount` verwenden |\n| Eigenmächtig einen Header `X-PAYMENT-REQUIRED` erstellen | In v1 den Body, in v2 `PAYMENT-REQUIRED` verwenden |\n| `isValid: true` als abgeschlossenen Zahlungseingang behandeln | Ergebnis von `/settle` separat prüfen |\n| Das oberste `to`-Feld der Transaktion als USDC-Empfänger behandeln | USDC `Transfer.to` prüfen |\n| Annehmen, dass Signierer und Transaktionsabsender identisch sind | Den Zahler der Autorisierung mit `Transfer.from` vergleichen |\n| Testnetzeingänge zum Umsatz addieren | Getrennte Bücher für Mainnet und Testnetz führen |\n| Bei jeder Zeitüberschreitung eine neue Zahlung erstellen | Zuerst bestehenden Auftrag und Autorisierungsstatus wiederherstellen |\n| SDK-Paketversion und Protokollversion gleichsetzen | Paketversion und `x402Version` getrennt verwalten |\n\nAuch die Domain-Informationen einer USDC-Signatur enthalten eine Versionszeichenfolge. Dieser Wert erfüllt einen anderen Zweck als die x402-Protokollversion. Die Struktur der Signatur-Domain finden Sie in der [ERC-3009-Spezifikation](https://eips.ethereum.org/EIPS/eip-3009).\n\n## Sicherheitsprüfung und Vertrauensgrenzen externer Dienste\n\nSteuern Sie die Beurteilung des Zahlungserfolgs auf dem Server. Auch der Antwort eines externen Facilitators wird ausdrücklich Vertrauen entgegengebracht. Die Architektur, die auch einen Eigenbetrieb ermöglicht, ist in der [Facilitator-Dokumentation](https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md) beschrieben.\n\n- Geben Sie Inhalte nicht aufgrund einer Erfolgsmeldung des Clients frei.\n- Vergleichen Sie Chain, Token, Betrag und Empfänger mit den Angaben des Servers.\n- Schreiben Sie private Schlüssel und Seed-Phrasen nicht in Logs.\n- Schließen Sie auch vollständige Autorisierungssignaturen aus allgemeinen Zugriffslogs aus.\n- Begrenzen Sie die Größe der Zahlungsheader und die Bearbeitungszeit von Anfragen.\n- Prüfen Sie, dass kostenpflichtige Antworten nicht in gemeinsam genutzten Caches verbleiben.\n- Bewahren Sie Testschlüssel und Produktivschlüssel getrennt auf.\n- Schaffen Sie bei einem Facilitator-Ausfall keinen Umgehungsweg ohne Zahlung.\n- Testen Sie den Ablauf von Autorisierungen und doppelte Anfragen tatsächlich.\n\nBei den festgeschriebenen Abhängigkeiten dieser Übung bestehen weiterhin Warnungen aus der Sicherheitsprüfung. `npm audit` meldete einen Sicherheitshinweis zu zod. Einzelheiten finden Sie im [GitHub-Sicherheitshinweis](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5).\n\n```bash\nnpm audit\n```\n\nPrüfen Sie vor dem Produktiveinsatz die SDK-Kompatibilität der korrigierten Version. Ein erzwungener Wechsel der Hauptversion kann das Verhalten verändern. Verwenden Sie diese Übung nicht als bereits sicherheitsgeprüfte Bereitstellungskonfiguration.\n\n### Vergleich von eigenem Server und Cloudflare Gateway\n\nBei Verwendung von Cloudflare Gateway ändert sich das Prüfverfahren des Ursprungsservers. Die Dokumentation vom 30. September 2026 nennt ausdrücklich die Verwendung von x402 v2. Die folgende Gegenüberstellung basiert auf der [Cloudflare-x402-Dokumentation](https://developers.cloudflare.com/monetization-gateway/x402/).\n\n| Merkmal | Express-Verfahren dieses Artikels | Cloudflare Monetization Gateway |\n|---|---|---|\n| Verarbeitung der Client-Zahlung | Express-Middleware | Gateway |\n| Prüfpunkt des Ursprungsservers | Anbindung an den ausgewählten Facilitator | Prüfung des JWT in `PAYMENT-CONTEXT` |\n| Übermittlung des Abwicklungsergebnisses | `PAYMENT-RESPONSE` der Middleware | Gateway erstellt den Abwicklungsbeleg |\n| Zusätzlich zu prüfen | Unterstützte Chains und Authentifizierung des Facilitators | JWT-Signaturprüfung und Schutz des Ursprungszugriffs |\n\n`PAYMENT-CONTEXT` ist ein Header zwischen Gateway und Ursprungsserver. Er ist nicht der Signaturheader eines gewöhnlichen x402-Clients. Richten Sie die Prüfung auf dem Ursprungsserver nach der [Cloudflare-Dokumentation zu Payment validation](https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/) aus.\n\nAuch hinter dem Gateway darf das JWT nicht nur dekodiert werden. Prüfen Sie die Signatur mit dem in der Dokumentation angegebenen Schlüssel. Sperren Sie kostenpflichtige Inhalte, wenn der Header fehlt oder die Prüfung fehlschlägt.\n\n## Tatsächliche Nutzung und Abwicklungsaufzeichnungen unterscheiden\n\nDie Anzahl der Onchain-Überweisungen allein belegt nicht den Konsum von Inhalten. Verknüpfen Sie für Betriebskennzahlen die Abwicklung mit der Auslieferung der Antwort. Dies ist ein Gestaltungsvorschlag auf Grundlage des Zahlungsablaufs und des Verhaltens bei erneuter Übertragung.\n\n| Aufzeichnung | Welche Frage sie beantwortet | Zusätzlich benötigte Aufzeichnung |\n|---|---|---|\n| 402-Antwort | Wie oft Zahlungsbedingungen angefordert wurden | Ob tatsächlich gezahlt wurde |\n| Erfolgreiche Prüfung | Ob die Autorisierung gültig war | Abwicklungsergebnis |\n| USDC-Transfer | Ob Vermögenswerte übertragen wurden | Auftragszuordnung |\n| Abgeschlossene Abwicklung pro Auftrag | Ob eine kostenpflichtige Anfrage bezahlt wurde | Auslieferungsstatus der Antwort |\n| Aufzeichnung der erneuten Auslieferung | Ob eine bereits bezahlte Anfrage wiederhergestellt wurde | Kennung zur Unterscheidung von neuen Zahlungen |\n\nKennzeichnen Sie Testanfragen getrennt von der tatsächlichen Nutzung. Markieren Sie auch Wiederholungen desselben Auftrags gesondert. Das Transaktionsvolumen allein darf nicht als API-Nachfrage oder Umsatzgarantie dargestellt werden.\n\n## Umstellung auf Base Mainnet\n\nZiehen Sie das Mainnet erst in Betracht, nachdem Sie die Erfolgs- und Fehlerabläufe im Testnetz geprüft haben. Die Umstellung ist nicht mit dem Ändern der Netzwerkzeichenfolge abgeschlossen. Das grundlegende Verfahren folgt dem [offiziellen Verkäuferleitfaden](https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet).\n\n1. Prüfen Sie, ob der ausgewählte Facilitator Base Mainnet unterstützt.\n2. Prüfen Sie unter `/supported` die Unterstützung von v2, `exact` und `eip155:8453`.\n3. Richten Sie die vom Anbieter verlangte Authentifizierung und die Nutzungsbedingungen ein.\n4. Ändern Sie das Netzwerk auf Server und Client gemeinsam.\n5. Ändern Sie die erlaubte USDC-Adresse des Clients auf die Mainnet-Adresse.\n6. Gleichen Sie den Betrag der 402-Antwort und die tatsächliche Empfängeradresse erneut ab.\n7. Binden Sie den Speicher für doppelte Anfragen und die Verfahren zur Fehlerwiederherstellung an.\n8. Schließen Sie die Sicherheitsprüfung der Produktivabhängigkeiten ab.\n9. Prüfen Sie mit dem festgelegten kleinen Betrag die tatsächliche Übertragung und Inhaltsauslieferung.\n\nMulti-Chain-Unterstützung bedeutet nicht, dass alle Kombinationen unterstützt werden. Prüfen Sie den Unterstützungsumfang von SDK und Facilitator gemeinsam. Maßgeblich ist die [Dokumentation zur Netzwerk- und Token-Unterstützung](https://docs.x402.org/core-concepts/network-and-token-support).","content_html":"\u003cp\u003ex402-Zahlungen werden implementiert, indem die Zahlungsbedingungen in der 402-Antwort der API übermittelt werden. Bereiten Sie Node.js und eine Test-Wallet vor. Prüfen Sie zunächst Signaturen und Abwicklung für v2 auf Base Sepolia. Konfigurieren Sie die kostenpflichtige Antwort so, dass sie erst nach erfolgreicher Abwicklung ausgeliefert wird.\u003c/p\u003e\n\u003cp\u003eDie Angaben zu Beträgen und Chains beruhen auf den als Quellen verlinkten offiziellen Dokumentationen von x402, Base und Circle.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#vorbereitung-und-installation\" class=\"anchor\" id=\"vorbereitung-und-installation\"\u003e\u003c/a\u003eVorbereitung und Installation\u003c/h2\u003e\n\u003cp\u003eBereiten Sie eine Entwicklungsumgebung vor, in der Sie die API ändern können, sowie eine Test-Wallet. Das Beispiel basiert auf Node.js 22 und x402 SDK 2.28.0. Der Installationsaufbau folgt dem \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-sellers\"\u003eoffiziellen Verkäuferleitfaden\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eHalten Sie eine EVM-Wallet-Adresse für den Zahlungsempfang bereit.\u003c/li\u003e\n\u003cli\u003eBereiten Sie eine separate Test-Wallet für Zahlungen vor.\u003c/li\u003e\n\u003cli\u003eBeschaffen Sie Base Sepolia Test-USDC für die Zahlungs-Wallet.\u003c/li\u003e\n\u003cli\u003eErstellen Sie das Übungsprojekt mit den folgenden Befehlen.\u003c/li\u003e\n\u003cli\u003eSpeichern Sie die nachfolgenden TypeScript-Dateien im selben Ordner.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003emkdir\u003c/span\u003e\u003cspan\u003e x402-demo\n\u003c/span\u003e\u003cspan\u003ecd\u003c/span\u003e\u003cspan\u003e x402-demo\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e init\u003c/span\u003e\u003cspan\u003e -y\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e pkg set type=module\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e install\u003c/span\u003e\u003cspan\u003e --save-exact\u003c/span\u003e\u003cspan\u003e express@5.3.0 viem@2.57.12 @x402/core@2.28.0 @x402/express@2.28.0 @x402/evm@2.28.0 @x402/fetch@2.28.0\n\u003c/span\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e install\u003c/span\u003e\u003cspan\u003e --save-dev --save-exact\u003c/span\u003e\u003cspan\u003e typescript tsx @types/node @types/express\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eDer empfangende Server benötigt den privaten Schlüssel der Empfänger-Wallet nicht. Konfigurieren Sie den privaten Zahlungsschlüssel so, dass er nur vom Client-Prozess gelesen wird. Das Signaturverfahren der Wallet richtet sich nach dem \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-buyers\"\u003eoffiziellen Käuferleitfaden\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eDieses Beispiel wurde durch Typprüfung und einen simulierten Zahlungsablauf geprüft. Eine tatsächliche Überweisung im Testnetz wurde damit noch nicht abgeschlossen. Prüfen Sie die Onchain-Ergebnisse bei der unten beschriebenen Ausführung selbst.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#vergleich-von-x402-v1-und-v2\" class=\"anchor\" id=\"vergleich-von-x402-v1-und-v2\"\u003e\u003c/a\u003eVergleich von x402 v1 und v2\u003c/h2\u003e\n\u003cp\u003eBei der Implementierung von v2 müssen Header und Felder im Body aufeinander abgestimmt sein. Wenn Sie nur die Header-Namen ändern, passt die Datenstruktur nicht. Die folgende Tabelle basiert auf dem \u003ca href=\"https://docs.x402.org/guides/migration-v1-to-v2\"\u003eoffiziellen Migrationsleitfaden\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eMerkmal\u003c/th\u003e\n\u003cth\u003ev1\u003c/th\u003e\n\u003cth\u003ev2\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eProtokollversion\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ex402Version: 1\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003ex402Version: 2\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eAnfängliche Zahlungsbedingungen\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003eJSON-Body der 402-Antwort\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eAntwortheader \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eSignierte Zahlungsdaten\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003eAnfrageheader \u003ccode\u003eX-PAYMENT\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eAnfrageheader \u003ccode\u003ePAYMENT-SIGNATURE\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eAbwicklungsergebnis\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003eAntwortheader \u003ccode\u003eX-PAYMENT-RESPONSE\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003eAntwortheader \u003ccode\u003ePAYMENT-RESPONSE\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eKennung für Base Mainnet\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ebase\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003eeip155:8453\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eKennung für Base Sepolia\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ebase-sepolia\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003eeip155:84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eBetragsfeld der Zahlungsbedingungen\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003emaxAmountRequired\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003eamount\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eRessourcenbeschreibung\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\n\u003ccode\u003eresource\u003c/code\u003e usw. innerhalb der Zahlungsbedingungen\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\n\u003ccode\u003eresource\u003c/code\u003e-Objekt auf oberster Ebene\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eBedingungen in der Zahlungs-Payload\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\n\u003ccode\u003escheme\u003c/code\u003e, \u003ccode\u003enetwork\u003c/code\u003e usw. auf oberster Ebene\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\n\u003ccode\u003eaccepted\u003c/code\u003e-Objekt mit den ausgewählten Bedingungen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eBeispiel für ein TypeScript-Paket\u003c/td\u003e\n\u003ctd data-label=\"v1\"\u003e\u003ccode\u003ex402-express\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"v2\"\u003e\u003ccode\u003e@x402/express\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eWo v1 die Zahlungsbedingungen übermittelt, ist in der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md\"\u003eHTTP-v1-Spezifikation\u003c/a\u003e festgelegt. Bei v2 ist der Header \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e der standardmäßige Übermittlungsort. Eine Implementierung kann zusätzlich einen Body zurückgeben; richten Sie die Verarbeitung jedoch nach dem Header aus.\u003c/p\u003e\n\u003cp\u003eDie \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md\"\u003eHTTP-v2-Spezifikation\u003c/a\u003e beschreibt den Statuscode wie folgt.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eDer Server zeigt mit dem HTTP-Statuscode 402 „Payment Required“ an, dass eine Zahlung erforderlich ist.\u003c/p\u003e\n\u003cp\u003eQuelle: x402 HTTP-v2-Spezifikation\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eDie Zahlungsheader von v2 enthalten Base64-kodiertes JSON. Base64 ist kein Verschlüsselungsverfahren. Verwenden Sie HTTPS für extern zugängliche Dienste.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#http-402-anfrage-und-zahlungsablauf\" class=\"anchor\" id=\"http-402-anfrage-und-zahlungsablauf\"\u003e\u003c/a\u003eHTTP-402-Anfrage und Zahlungsablauf\u003c/h2\u003e\n\u003cp\u003eDiese Übung verwendet den grundlegenden Autorisierungsablauf des EVM-Verfahrens \u003ccode\u003eexact\u003c/code\u003e. Bei \u003ccode\u003eexact\u003c/code\u003e wird ein festgelegter Betrag bezahlt. Der Ablauf folgt der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md\"\u003eKernspezifikation von x402 v2\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eDer Client ruft die kostenpflichtige API ohne Zahlungsinformationen auf.\u003c/li\u003e\n\u003cli\u003eDer Server gibt HTTP 402 und \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e zurück.\u003c/li\u003e\n\u003cli\u003eDer Client wählt zulässige Bedingungen aus \u003ccode\u003eaccepts\u003c/code\u003e aus.\u003c/li\u003e\n\u003cli\u003eDas SDK signiert eine Zahlungsautorisierung für die ausgewählten Bedingungen.\u003c/li\u003e\n\u003cli\u003eDer Client wiederholt die Anfrage mit \u003ccode\u003ePAYMENT-SIGNATURE\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eDer Server prüft die Autorisierung über \u003ccode\u003e/verify\u003c/code\u003e des Facilitators.\u003c/li\u003e\n\u003cli\u003eNach erfolgreicher Prüfung führt der Server die Ressourcenverarbeitung aus.\u003c/li\u003e\n\u003cli\u003eDer Server fordert über \u003ccode\u003e/settle\u003c/code\u003e die Abwicklung an.\u003c/li\u003e\n\u003cli\u003eNach erfolgreicher Abwicklung liefert er den kostenpflichtigen Body und \u003ccode\u003ePAYMENT-RESPONSE\u003c/code\u003e aus.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eDiese Reihenfolge ist kein festgelegter Ablauf für alle Zahlungsverfahren. v2 definiert auch Abläufe mit einem anderen Abwicklungszeitpunkt. Der folgende Code lässt nur den grundlegenden Ablauf \u003ccode\u003eauthorization\u003c/code\u003e zu.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#rollen-von-ressourcenserver-und-facilitator\" class=\"anchor\" id=\"rollen-von-ressourcenserver-und-facilitator\"\u003e\u003c/a\u003eRollen von Ressourcenserver und Facilitator\u003c/h3\u003e\n\u003cp\u003eDer Ressourcenserver legt Preise und Zugangsbedingungen für Inhalte fest. Der Facilitator übernimmt die Zahlungsprüfung und Abwicklung. Die Rollenverteilung richtet sich nach der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md\"\u003eoffiziellen Facilitator-Dokumentation\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eKomponente\u003c/th\u003e\n\u003cth\u003eAufgabe\u003c/th\u003e\n\u003cth\u003eZustand, der nicht als Erfolg gelten darf\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Komponente\"\u003eClient\u003c/td\u003e\n\u003ctd data-label=\"Aufgabe\"\u003eBedingungen auswählen und Zahlungsautorisierung signieren\u003c/td\u003e\n\u003ctd data-label=\"Zustand, der nicht als Erfolg gelten darf\"\u003eNur die Signatur wurde erstellt\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Komponente\"\u003eRessourcenserver\u003c/td\u003e\n\u003ctd data-label=\"Aufgabe\"\u003ePreis angeben und kostenpflichtige Antworten steuern\u003c/td\u003e\n\u003ctd data-label=\"Zustand, der nicht als Erfolg gelten darf\"\u003eDer Client behauptet, die Zahlung sei erfolgreich\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Komponente\"\u003eFacilitator \u003ccode\u003e/verify\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"Aufgabe\"\u003eGültigkeit von Signatur und Zahlungsbedingungen prüfen\u003c/td\u003e\n\u003ctd data-label=\"Zustand, der nicht als Erfolg gelten darf\"\u003eEs wurde lediglich \u003ccode\u003eisValid: true\u003c/code\u003e empfangen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Komponente\"\u003eFacilitator \u003ccode\u003e/settle\u003c/code\u003e\n\u003c/td\u003e\n\u003ctd data-label=\"Aufgabe\"\u003eIn dieser Übung die Onchain-Zahlung ausführen und das Ergebnis zurückgeben\u003c/td\u003e\n\u003ctd data-label=\"Zustand, der nicht als Erfolg gelten darf\"\u003eDie Transaktion wurde gesendet, das Ergebnis aber noch nicht bestätigt\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003e\u003ccode\u003e/verify\u003c/code\u003e ist eine Prüfung, die den Onchain-Zustand nicht verändert. Eine erfolgreiche Prüfung bedeutet daher nicht, dass der Zahlungseingang abgeschlossen ist. Guthaben oder Autorisierungsstatus können sich auch nach der Prüfung noch ändern.\u003c/p\u003e\n\u003cp\u003eSperren Sie den kostenpflichtigen Body, wenn Prüfung oder Abwicklung fehlschlagen. Ein Vorgehen, das den Zugriff sperrt, solange kein Erfolg bestätigt ist, wird als fail-closed bezeichnet. Dieses Verhalten lässt sich auch in der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts\"\u003eoffiziellen Express-Implementierung\u003c/a\u003e nachvollziehen.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#vergleich-von-base-mainnet-und-testnetz\" class=\"anchor\" id=\"vergleich-von-base-mainnet-und-testnetz\"\u003e\u003c/a\u003eVergleich von Base Mainnet und Testnetz\u003c/h2\u003e\n\u003cp\u003eVerwenden Sie beim ersten Durchlauf ausschließlich Base Sepolia. Circle stellt ausdrücklich fest, dass USDC im Testnetz keinen finanziellen Wert haben. Die Adressen stammen aus der \u003ca href=\"https://developers.circle.com/stablecoins/usdc-contract-addresses\"\u003eListe der USDC-Contract-Adressen von Circle\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eMerkmal\u003c/th\u003e\n\u003cth\u003eBase Mainnet\u003c/th\u003e\n\u003cth\u003eBase Sepolia Testnetz\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eZweck\u003c/td\u003e\n\u003ctd data-label=\"Base Mainnet\"\u003eZahlungen mit realen Vermögenswerten\u003c/td\u003e\n\u003ctd data-label=\"Base Sepolia Testnetz\"\u003eImplementierung und Fehlerbehandlung testen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eChain ID\u003c/td\u003e\n\u003ctd data-label=\"Base Mainnet\"\u003e\u003ccode\u003e8453\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Base Sepolia Testnetz\"\u003e\u003ccode\u003e84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eNetzwerk für x402 v2\u003c/td\u003e\n\u003ctd data-label=\"Base Mainnet\"\u003e\u003ccode\u003eeip155:8453\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Base Sepolia Testnetz\"\u003e\u003ccode\u003eeip155:84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eUSDC-Contract\u003c/td\u003e\n\u003ctd data-label=\"Base Mainnet\"\u003e\u003ccode\u003e0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Base Sepolia Testnetz\"\u003e\u003ccode\u003e0x036CbD53842c5426634e7929541eC2318f3dCF7e\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eÖffentlicher RPC\u003c/td\u003e\n\u003ctd data-label=\"Base Mainnet\"\u003e\u003ccode\u003ehttps://mainnet.base.org\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Base Sepolia Testnetz\"\u003e\u003ccode\u003ehttps://sepolia.base.org\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eFinanzieller Wert des Tokens\u003c/td\u003e\n\u003ctd data-label=\"Base Mainnet\"\u003eVermögenswert mit realem finanziellem Wert\u003c/td\u003e\n\u003ctd data-label=\"Base Sepolia Testnetz\"\u003eKein finanzieller Wert\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003ePrüfen Sie Chain ID und RPC in der \u003ca href=\"https://docs.base.org/get-started/connect-to-base\"\u003eBase-Netzwerkdokumentation\u003c/a\u003e. Auch bei derselben Wallet-Adresse sind die Guthaben auf unterschiedlichen Chains getrennt. Ein Erfolg im Testnetz darf nicht als tatsächlicher Umsatz verbucht werden.\u003c/p\u003e\n\u003cp\u003eTest-USDC können Sie beim \u003ca href=\"https://faucet.circle.com/\"\u003eCircle Testnet Faucet\u003c/a\u003e anfordern. Wählen Sie Base Sepolia als Netzwerk. Geben Sie als Empfängeradresse die Adresse der Test-Wallet für Zahlungen ein.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#kostenpflichtige-api-mit-nodejs-implementieren\" class=\"anchor\" id=\"kostenpflichtige-api-mit-nodejs-implementieren\"\u003e\u003c/a\u003eKostenpflichtige API mit Node.js implementieren\u003c/h2\u003e\n\u003cp\u003eSchalten Sie \u003ccode\u003epaymentMiddleware\u003c/code\u003e vor die kostenpflichtige Route. Das folgende Beispiel verlangt \u003cstrong\u003e0.001 USDC\u003c/strong\u003e pro Aufruf. Der Betrag entspricht dem Beispielpreis aus dem offiziellen Verkäuferleitfaden. (Geprüfter Wert: 0.001 USDC pro Aufruf · Quelle: docs.x402.org · geprüft am 2026-10-28)\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#serverdatei\" class=\"anchor\" id=\"serverdatei\"\u003e\u003c/a\u003eServerdatei\u003c/h3\u003e\n\u003cp\u003eSpeichern Sie den folgenden Code als \u003ccode\u003eserver.ts\u003c/code\u003e. Der Server nimmt Anfragen nur über die lokale Schnittstelle an. Die Empfängeradresse wird aus der Umgebungsvariablen \u003ccode\u003ePAY_TO\u003c/code\u003e gelesen.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eimport express from \"express\";\n\u003c/span\u003e\u003cspan\u003eimport { getAddress, zeroAddress } from \"viem\";\n\u003c/span\u003e\u003cspan\u003eimport { paymentMiddleware } from \"@x402/express\";\n\u003c/span\u003e\u003cspan\u003eimport { HTTPFacilitatorClient, x402ResourceServer } from \"@x402/core/server\";\n\u003c/span\u003e\u003cspan\u003eimport { ExactEvmScheme } from \"@x402/evm/exact/server\";\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst payTo = getAddress(process.env.PAY_TO ?? \"\");\n\u003c/span\u003e\u003cspan\u003eif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\n\u003c/span\u003e\u003cspan\u003econst network = \"eip155:84532\";\n\u003c/span\u003e\u003cspan\u003econst resourceServer = new x402ResourceServer(\n\u003c/span\u003e\u003cspan\u003e  new HTTPFacilitatorClient({ url: \"https://x402.org/facilitator\" }),\n\u003c/span\u003e\u003cspan\u003e).register(network, new ExactEvmScheme());\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst app = express();\n\u003c/span\u003e\u003cspan\u003eapp.use((_req, res, next) =\u0026gt; {\n\u003c/span\u003e\u003cspan\u003e  res.setHeader(\"Cache-Control\", \"private, no-store\");\n\u003c/span\u003e\u003cspan\u003e  next();\n\u003c/span\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003cspan\u003eapp.use(paymentMiddleware({\n\u003c/span\u003e\u003cspan\u003e  \"GET /paid-data\": {\n\u003c/span\u003e\u003cspan\u003e    accepts: [{ scheme: \"exact\", price: \"$0.001\", network, payTo }],\n\u003c/span\u003e\u003cspan\u003e    description: \"Sample paid JSON\",\n\u003c/span\u003e\u003cspan\u003e    mimeType: \"application/json\",\n\u003c/span\u003e\u003cspan\u003e  },\n\u003c/span\u003e\u003cspan\u003e}, resourceServer));\n\u003c/span\u003e\u003cspan\u003eapp.get(\"/paid-data\", (_req, res) =\u0026gt; {\n\u003c/span\u003e\u003cspan\u003e  res.json({ content: \"Paid sample content\" });\n\u003c/span\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003cspan\u003eapp.listen(4021, \"127.0.0.1\");\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003ehttps://x402.org/facilitator\u003c/code\u003e ist die Testadresse aus dem offiziellen Leitfaden. In diesem Beispiel wird sie für die Abwicklung auf Base Sepolia verwendet. Informationen zur Auswahl eines Facilitators für den Produktivbetrieb finden Sie im \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet\"\u003eMainnet-Verfahren des Verkäuferleitfadens\u003c/a\u003e.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#beispiel-zur-preisberechnung\" class=\"anchor\" id=\"beispiel-zur-preisberechnung\"\u003e\u003c/a\u003eBeispiel zur Preisberechnung\u003c/h3\u003e\n\u003cp\u003eDer Beispielpreis entspricht \u003ccode\u003e1000\u003c/code\u003e kleinsten USDC-Einheiten. USDC hat 6 Nachkommastellen. Die Preisumrechnung des SDK richtet sich nach der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts\"\u003eEVM-Serverimplementierung\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003e0.001 USDC × 10^6 = 1000 최소 단위\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eZu prüfender Wert\u003c/th\u003e\n\u003cth\u003eErwarteter Wert in diesem Beispiel\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Zu prüfender Wert\"\u003e\n\u003ccode\u003eprice\u003c/code\u003e in der Serverkonfiguration\u003c/td\u003e\n\u003ctd data-label=\"Erwarteter Wert in diesem Beispiel\"\u003e\u003ccode\u003e\"$0.001\"\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Zu prüfender Wert\"\u003e\n\u003ccode\u003eamount\u003c/code\u003e in den Zahlungsbedingungen der 402-Antwort\u003c/td\u003e\n\u003ctd data-label=\"Erwarteter Wert in diesem Beispiel\"\u003e\u003ccode\u003e\"1000\"\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Zu prüfender Wert\"\u003e\n\u003ccode\u003easset\u003c/code\u003e in den Zahlungsbedingungen\u003c/td\u003e\n\u003ctd data-label=\"Erwarteter Wert in diesem Beispiel\"\u003eUSDC-Contract auf Base Sepolia\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Zu prüfender Wert\"\u003e\n\u003ccode\u003epayTo\u003c/code\u003e in den Zahlungsbedingungen\u003c/td\u003e\n\u003ctd data-label=\"Erwarteter Wert in diesem Beispiel\"\u003eKonfigurierte Empfängeradresse\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Zu prüfender Wert\"\u003e\n\u003ccode\u003enetwork\u003c/code\u003e in den Zahlungsbedingungen\u003c/td\u003e\n\u003ctd data-label=\"Erwarteter Wert in diesem Beispiel\"\u003e\u003ccode\u003eeip155:84532\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003e\u003ccode\u003eprice\u003c/code\u003e ist ein Konfigurationswert des SDK. In den tatsächlichen Zahlungsbedingungen von v2 wird \u003ccode\u003eamount\u003c/code\u003e übermittelt. Vergleichen Sie ganzzahlige Beträge als Zeichenfolgen oder \u003ccode\u003ebigint\u003c/code\u003e.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#server-starten-und-402-pr%C3%BCfen\" class=\"anchor\" id=\"server-starten-und-402-prüfen\"\u003e\u003c/a\u003eServer starten und 402 prüfen\u003c/h3\u003e\n\u003cp\u003eStarten Sie den Server im ersten Bash-Terminal. Der eingegebene Wert ist die öffentliche Empfängeradresse, nicht der private Schlüssel. Lassen Sie dieses Terminal während der Ausführung geöffnet.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eread \u003c/span\u003e\u003cspan\u003e-r -p \u003c/span\u003e\u003cspan\u003e'\u003c/span\u003e\u003cspan\u003e수취 지갑 주소: \u003c/span\u003e\u003cspan\u003e' PAY_TO\n\u003c/span\u003e\u003cspan\u003eexport \u003c/span\u003e\u003cspan\u003ePAY_TO\n\u003c/span\u003e\u003cspan\u003enpx\u003c/span\u003e\u003cspan\u003e tsx server.ts\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eSenden Sie aus einem zweiten Terminal eine Anfrage ohne Zahlung. Der folgende Befehl signiert keine Zahlung. Er gibt den HTTP-Status und die dekodierten Zahlungsbedingungen aus.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003enode\u003c/span\u003e\u003cspan\u003e --input-type\u003c/span\u003e\u003cspan\u003e=module \u0026lt;\u0026lt;'\u003c/span\u003e\u003cspan\u003eJS\u003c/span\u003e\u003cspan\u003e'\n\u003c/span\u003e\u003cspan\u003econst response = await fetch(\"http://127.0.0.1:4021/paid-data\");\n\u003c/span\u003e\u003cspan\u003econst header = response.headers.get(\"PAYMENT-REQUIRED\");\n\u003c/span\u003e\u003cspan\u003econsole.log(response.status);\n\u003c/span\u003e\u003cspan\u003econsole.log(header \u0026amp;\u0026amp; JSON.parse(\n\u003c/span\u003e\u003cspan\u003e  Buffer.from(header, \"base64\").toString(\"utf8\")\n\u003c/span\u003e\u003cspan\u003e));\n\u003c/span\u003e\u003cspan\u003eJS\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eDie reguläre Antwort ohne Zahlung ist HTTP 402. Vergleichen Sie die ausgegebenen Bedingungen mit der obigen Tabelle. Falls die kostenpflichtigen Inhalte direkt zurückgegeben werden, korrigieren Sie zuerst den Schutz der Route.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#zahlungsbedingungen-ausw%C3%A4hlen-und-client-implementieren\" class=\"anchor\" id=\"zahlungsbedingungen-auswählen-und-client-implementieren\"\u003e\u003c/a\u003eZahlungsbedingungen auswählen und Client implementieren\u003c/h2\u003e\n\u003cp\u003eBeschränken Sie den Client darauf, nur erlaubte Bedingungen zu signieren. Dieses Beispiel erlaubt ausschließlich den festgelegten Preis in USDC auf Base Sepolia. Der Filter für Zahlungsoptionen verwendet \u003ccode\u003eregisterPolicy\u003c/code\u003e aus der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts\"\u003eoffiziellen x402Client-Implementierung\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eSpeichern Sie den folgenden Code als \u003ccode\u003eclient.ts\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eSpeichern Sie auch \u003ccode\u003echeck-transfer.ts\u003c/code\u003e aus dem nächsten Abschnitt.\u003c/li\u003e\n\u003cli\u003eFahren Sie erst mit der Ausführung fort, wenn beide Dateien vorliegen.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eimport { writeFile } from \"node:fs/promises\";\n\u003c/span\u003e\u003cspan\u003eimport { getAddress, zeroAddress, type Hex, type Hash } from \"viem\";\n\u003c/span\u003e\u003cspan\u003eimport { privateKeyToAccount } from \"viem/accounts\";\n\u003c/span\u003e\u003cspan\u003eimport { x402Client, wrapFetchWithPayment } from \"@x402/fetch\";\n\u003c/span\u003e\u003cspan\u003eimport { decodePaymentResponseHeader } from \"@x402/core/http\";\n\u003c/span\u003e\u003cspan\u003eimport { ExactEvmScheme } from \"@x402/evm/exact/client\";\n\u003c/span\u003e\u003cspan\u003eimport { checkTransfer } from \"./check-transfer.js\";\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst key = process.env.EVM_PRIVATE_KEY ?? \"\";\n\u003c/span\u003e\u003cspan\u003eif (!/^0x[0-9a-fA-F]{64}$/.test(key)) throw new Error(\"Invalid test key\");\n\u003c/span\u003e\u003cspan\u003econst signer = privateKeyToAccount(key as Hex);\n\u003c/span\u003e\u003cspan\u003econst payTo = getAddress(process.env.PAY_TO ?? \"\");\n\u003c/span\u003e\u003cspan\u003eif (payTo === zeroAddress) throw new Error(\"Invalid payTo\");\n\u003c/span\u003e\u003cspan\u003econst network = \"eip155:84532\";\n\u003c/span\u003e\u003cspan\u003econst token = \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\";\n\u003c/span\u003e\u003cspan\u003econst client = new x402Client().register(network, new ExactEvmScheme(signer));\n\u003c/span\u003e\u003cspan\u003eclient.registerPolicy((version, options) =\u0026gt; version === 2\n\u003c/span\u003e\u003cspan\u003e  ? options.filter(r =\u0026gt;\n\u003c/span\u003e\u003cspan\u003e      r.scheme === \"exact\" \u0026amp;\u0026amp; r.network === network \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      r.asset.toLowerCase() === token.toLowerCase() \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      r.payTo.toLowerCase() === payTo.toLowerCase() \u0026amp;\u0026amp; r.amount === \"1000\" \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      (!r.extra?.assetTransferMethod || r.extra.assetTransferMethod === \"eip3009\") \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e      (!r.extra?.paymentFlow || r.extra.paymentFlow === \"authorization\"))\n\u003c/span\u003e\u003cspan\u003e  : []);\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst paidFetch = wrapFetchWithPayment(fetch, client);\n\u003c/span\u003e\u003cspan\u003econst response = await paidFetch(\"http://127.0.0.1:4021/paid-data\", {\n\u003c/span\u003e\u003cspan\u003e  redirect: \"error\",\n\u003c/span\u003e\u003cspan\u003e});\n\u003c/span\u003e\u003cspan\u003econst raw = response.headers.get(\"PAYMENT-RESPONSE\");\n\u003c/span\u003e\u003cspan\u003eif (!raw) throw new Error(`No settlement receipt: HTTP ${response.status}`);\n\u003c/span\u003e\u003cspan\u003econst settlement = decodePaymentResponseHeader(raw);\n\u003c/span\u003e\u003cspan\u003eawait writeFile(\"settlement.json\", JSON.stringify(settlement, null, 2));\n\u003c/span\u003e\u003cspan\u003eif (!response.ok || !settlement.success || settlement.network !== network) {\n\u003c/span\u003e\u003cspan\u003e  throw new Error(\"Payment unresolved; inspect settlement.json before retrying\");\n\u003c/span\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003cspan\u003econst evidence = await checkTransfer(\n\u003c/span\u003e\u003cspan\u003e  network, settlement.transaction as Hash, signer.address, payTo, 1000n,\n\u003c/span\u003e\u003cspan\u003e);\n\u003c/span\u003e\u003cspan\u003eawait writeFile(\"transfer.json\", JSON.stringify(evidence, null, 2));\n\u003c/span\u003e\u003cspan\u003econsole.log(await response.text());\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003ewrapFetchWithPayment\u003c/code\u003e übernimmt die Verarbeitung von 402 und die erneute Anfrage mit Signatur. Die Verwendung folgt dem \u003ca href=\"https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch\"\u003eoffiziellen fetch-Beispiel\u003c/a\u003e. Wenn keine erlaubten Zahlungsbedingungen vorliegen, wird die Erstellung der Zahlung abgebrochen.\u003c/p\u003e\n\u003cp\u003eDieser Client kann auch in KI-Agenten verwendet werden. Eine Preisgrenze pro Aufruf ist jedoch keine Grenze für die Gesamtausgaben. Verwalten Sie das Budget für wiederholte Aufrufe des Agenten separat.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#usdc-transfer-ereignisse-pr%C3%BCfen\" class=\"anchor\" id=\"usdc-transfer-ereignisse-prüfen\"\u003e\u003c/a\u003eUSDC-Transfer-Ereignisse prüfen\u003c/h2\u003e\n\u003cp\u003ePrüfen Sie die USDC-Transfer-Logs anhand des Transaktionshashs aus dem Abwicklungsergebnis. Ein erfolgreicher Transaktionsstatus allein bestätigt noch nicht den Empfänger. Die Felder von \u003ccode\u003eTransfer\u003c/code\u003e richten sich nach dem \u003ca href=\"https://eips.ethereum.org/EIPS/eip-20\"\u003eERC-20-Standard\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eFür die Prüfung werden folgende Angaben benötigt.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003ePrüfpunkt\u003c/th\u003e\n\u003cth\u003eVergleichswert\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Prüfpunkt\"\u003eChain ID des RPC\u003c/td\u003e\n\u003ctd data-label=\"Vergleichswert\"\u003eVom Server zugelassene Chain\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Prüfpunkt\"\u003e\n\u003ccode\u003estatus\u003c/code\u003e des Transaktionsbelegs\u003c/td\u003e\n\u003ctd data-label=\"Vergleichswert\"\u003eErfolgsstatus\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Prüfpunkt\"\u003eAdresse, die das Ereignis ausgelöst hat\u003c/td\u003e\n\u003ctd data-label=\"Vergleichswert\"\u003eOffizieller USDC-Contract der betreffenden Chain\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Prüfpunkt\"\u003e\u003ccode\u003eTransfer.from\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Vergleichswert\"\u003eBestätigter Zahler\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Prüfpunkt\"\u003e\u003ccode\u003eTransfer.to\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Vergleichswert\"\u003eVom Server festgelegte Empfängeradresse\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Prüfpunkt\"\u003e\u003ccode\u003eTransfer.value\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Vergleichswert\"\u003eVom Server verlangter Betrag in kleinsten Einheiten\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eSpeichern Sie den folgenden Code als \u003ccode\u003echeck-transfer.ts\u003c/code\u003e. Die Abfrage verwendet \u003ca href=\"https://viem.sh/docs/actions/public/getTransactionReceipt\"\u003egetTransactionReceipt\u003c/a\u003e von viem. Die Auswertung der Ereignisse richtet sich nach \u003ca href=\"https://viem.sh/docs/contract/parseEventLogs\"\u003eparseEventLogs\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003eimport {\n\u003c/span\u003e\u003cspan\u003e  createPublicClient, http, getAddress, parseEventLogs,\n\u003c/span\u003e\u003cspan\u003e  erc20Abi, type Address, type Hash,\n\u003c/span\u003e\u003cspan\u003e} from \"viem\";\n\u003c/span\u003e\u003cspan\u003eimport { base, baseSepolia } from \"viem/chains\";\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003econst configs = {\n\u003c/span\u003e\u003cspan\u003e  \"eip155:84532\": {\n\u003c/span\u003e\u003cspan\u003e    chain: baseSepolia,\n\u003c/span\u003e\u003cspan\u003e    rpc: \"https://sepolia.base.org\",\n\u003c/span\u003e\u003cspan\u003e    token: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n\u003c/span\u003e\u003cspan\u003e  },\n\u003c/span\u003e\u003cspan\u003e  \"eip155:8453\": {\n\u003c/span\u003e\u003cspan\u003e    chain: base,\n\u003c/span\u003e\u003cspan\u003e    rpc: \"https://mainnet.base.org\",\n\u003c/span\u003e\u003cspan\u003e    token: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n\u003c/span\u003e\u003cspan\u003e  },\n\u003c/span\u003e\u003cspan\u003e} as const;\n\u003c/span\u003e\u003cspan\u003e\n\u003c/span\u003e\u003cspan\u003eexport async function checkTransfer(\n\u003c/span\u003e\u003cspan\u003e  network: keyof typeof configs, hash: Hash,\n\u003c/span\u003e\u003cspan\u003e  payer: Address, payTo: Address, amount: bigint,\n\u003c/span\u003e\u003cspan\u003e) {\n\u003c/span\u003e\u003cspan\u003e  const cfg = configs[network];\n\u003c/span\u003e\u003cspan\u003e  const rpc = createPublicClient({ chain: cfg.chain, transport: http(cfg.rpc) });\n\u003c/span\u003e\u003cspan\u003e  if (await rpc.getChainId() !== cfg.chain.id) throw new Error(\"Wrong chain\");\n\u003c/span\u003e\u003cspan\u003e  const receipt = await rpc.getTransactionReceipt({ hash });\n\u003c/span\u003e\u003cspan\u003e  if (receipt.status !== \"success\") throw new Error(\"Transaction failed\");\n\u003c/span\u003e\u003cspan\u003e  const logs = parseEventLogs({\n\u003c/span\u003e\u003cspan\u003e    abi: erc20Abi,\n\u003c/span\u003e\u003cspan\u003e    eventName: \"Transfer\",\n\u003c/span\u003e\u003cspan\u003e    logs: receipt.logs.filter(\n\u003c/span\u003e\u003cspan\u003e      log =\u0026gt; getAddress(log.address) === getAddress(cfg.token),\n\u003c/span\u003e\u003cspan\u003e    ),\n\u003c/span\u003e\u003cspan\u003e    strict: true,\n\u003c/span\u003e\u003cspan\u003e  });\n\u003c/span\u003e\u003cspan\u003e  const transfer = logs.find(log =\u0026gt;\n\u003c/span\u003e\u003cspan\u003e    getAddress(log.args.from) === getAddress(payer) \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e    getAddress(log.args.to) === getAddress(payTo) \u0026amp;\u0026amp;\n\u003c/span\u003e\u003cspan\u003e    log.args.value === amount,\n\u003c/span\u003e\u003cspan\u003e  );\n\u003c/span\u003e\u003cspan\u003e  if (!transfer) throw new Error(\"Matching USDC Transfer not found\");\n\u003c/span\u003e\u003cspan\u003e  return {\n\u003c/span\u003e\u003cspan\u003e    network, transaction: hash, logIndex: transfer.logIndex,\n\u003c/span\u003e\u003cspan\u003e    blockHash: receipt.blockHash, blockNumber: receipt.blockNumber.toString(),\n\u003c/span\u003e\u003cspan\u003e  };\n\u003c/span\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eDiese Funktion bestätigt den USDC-Transfer in der betreffenden Transaktion. Ob er einem bestimmten API-Auftrag zugeordnet ist, muss separat geprüft werden. Verwenden Sie auf einem Produktivserver die gespeicherten Auftragsbedingungen als Vergleichswerte.\u003c/p\u003e\n\u003cp\u003eVertrauen Sie einer vom Client hochgeladenen Datei \u003ccode\u003etransfer.json\u003c/code\u003e nicht als Nachweis für die Zugangsberechtigung. Der Server dieses Beispiels verwendet die Prüf- und Abwicklungsergebnisse des Facilitators. Soll eine unabhängige Abfrage Voraussetzung für den Zugriff sein, muss sie auf dem Server ausgeführt werden.\u003c/p\u003e\n\u003cp\u003eEine fehlgeschlagene Belegabfrage bedeutet nicht automatisch, dass die Zahlung fehlgeschlagen ist. Fragen Sie bei einem RPC-Fehler den gespeicherten Transaktionshash erneut ab. Die Anzahl zusätzlicher Bestätigungen und der Umgang mit Chain-Reorganisationen werden in den Betriebsrichtlinien festgelegt.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#testzahlung-ausf%C3%BChren-und-ergebnisse-pr%C3%BCfen\" class=\"anchor\" id=\"testzahlung-ausführen-und-ergebnisse-prüfen\"\u003e\u003c/a\u003eTestzahlung ausführen und Ergebnisse prüfen\u003c/h2\u003e\n\u003cp\u003eSpeichern Sie alle Dateien und führen Sie den Test mit der Test-Wallet aus. Die Typprüfung führt weder Signaturen noch Überweisungen aus. Der folgende Befehl verwendet die zuvor installierten TypeScript-Werkzeuge.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ePrüfen Sie die Typen mit dem folgenden Befehl.\u003c/li\u003e\n\u003cli\u003eGeben Sie im zweiten Terminal dieselbe Empfängeradresse wie auf dem Server ein.\u003c/li\u003e\n\u003cli\u003eGeben Sie den privaten Schlüssel der Test-Zahlungs-Wallet verdeckt ein.\u003c/li\u003e\n\u003cli\u003eFühren Sie den Client einmal aus.\u003c/li\u003e\n\u003cli\u003ePrüfen Sie das gespeicherte Abwicklungsergebnis und die Transfer-Logs.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003enpx\u003c/span\u003e\u003cspan\u003e tsc\u003c/span\u003e\u003cspan\u003e --noEmit --strict --skipLibCheck --target\u003c/span\u003e\u003cspan\u003e ES2022\u003c/span\u003e\u003cspan\u003e --module\u003c/span\u003e\u003cspan\u003e NodeNext\u003c/span\u003e\u003cspan\u003e --moduleResolution\u003c/span\u003e\u003cspan\u003e NodeNext server.ts client.ts check-transfer.ts\n\u003c/span\u003e\u003cspan\u003eread \u003c/span\u003e\u003cspan\u003e-r -p \u003c/span\u003e\u003cspan\u003e'\u003c/span\u003e\u003cspan\u003e같은 수취 지갑 주소: \u003c/span\u003e\u003cspan\u003e' PAY_TO\n\u003c/span\u003e\u003cspan\u003eread \u003c/span\u003e\u003cspan\u003e-r -s -p \u003c/span\u003e\u003cspan\u003e'\u003c/span\u003e\u003cspan\u003e테스트 결제 지갑 개인키: \u003c/span\u003e\u003cspan\u003e' EVM_PRIVATE_KEY\n\u003c/span\u003e\u003cspan\u003eexport \u003c/span\u003e\u003cspan\u003ePAY_TO EVM_PRIVATE_KEY\n\u003c/span\u003e\u003cspan\u003enpx\u003c/span\u003e\u003cspan\u003e tsx client.ts\n\u003c/span\u003e\u003cspan\u003eunset\u003c/span\u003e\u003cspan\u003e EVM_PRIVATE_KEY\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eErgebnis\u003c/th\u003e\n\u003cth\u003eBedeutung\u003c/th\u003e\n\u003cth\u003eZu prüfen\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Ergebnis\"\u003e\u003ccode\u003esettlement.json\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Bedeutung\"\u003eVom Server zurückgegebenes Abwicklungsergebnis\u003c/td\u003e\n\u003ctd data-label=\"Zu prüfen\"\u003e\n\u003ccode\u003esuccess\u003c/code\u003e, \u003ccode\u003enetwork\u003c/code\u003e, \u003ccode\u003etransaction\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Ergebnis\"\u003e\u003ccode\u003etransfer.json\u003c/code\u003e\u003c/td\u003e\n\u003ctd data-label=\"Bedeutung\"\u003eBei der RPC-Abfrage gefundener Transferdatensatz\u003c/td\u003e\n\u003ctd data-label=\"Zu prüfen\"\u003eChain, Transaktionshash, Log-Position, Blockinformationen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Ergebnis\"\u003eKostenpflichtiger Body in der Konsole\u003c/td\u003e\n\u003ctd data-label=\"Bedeutung\"\u003eDaten, die nach der Prüfung durch diesen Client ausgegeben wurden\u003c/td\u003e\n\u003ctd data-label=\"Zu prüfen\"\u003ePrüfen, ob es sich um die angeforderten Inhalte handelt\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eEin erneuter Start des Clients kann eine neue Zahlung auslösen. Dieses Minimalbeispiel enthält keinen auftragsbezogenen Speicher zur Verhinderung von Duplikaten. Ergänzen Sie eine Wiederholungsfunktion erst, wenn die Voraussetzungen des nächsten Abschnitts erfüllt sind.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#behandlung-verschiedener-pr%C3%BCfungsfehler\" class=\"anchor\" id=\"behandlung-verschiedener-prüfungsfehler\"\u003e\u003c/a\u003eBehandlung verschiedener Prüfungsfehler\u003c/h2\u003e\n\u003cp\u003ePrüfen Sie bei Fehlertests, dass der kostenpflichtige Body nicht offengelegt wird. Wenn Sie nur den HTTP-Status prüfen, können Sie eine fehlende Zugriffssperre übersehen. Als Referenz für das Verhalten dient die \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts\"\u003eoffizielle Express-Middleware\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eTestbedingung\u003c/th\u003e\n\u003cth\u003eErwartetes Verhalten\u003c/th\u003e\n\u003cth\u003eZusätzliche Prüfung\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eZahlungsheader fehlt\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003e402 und Zahlungsbedingungen zurückgeben\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eKein kostenpflichtiger Body\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eAnderer Token oder Empfänger angegeben\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003eDurch Client-Richtlinie ablehnen\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eKeine Signatur erstellen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eUngültige Signatur\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003eWegen fehlgeschlagener Prüfung sperren\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eKostenpflichtigen Handler nicht ausführen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eUnzureichendes Guthaben\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003eWegen fehlgeschlagener Prüfung oder Abwicklung sperren\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eNicht als erfolgreiche Abwicklung verbuchen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eAbwicklungsergebnis meldet Fehler\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003eKostenpflichtige Antwort sperren\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eAuch vorbereiteten Body nicht senden\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eVerzögerte Antwort des Facilitators\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003eOhne Erfolgsbestätigung im ausstehenden Zustand halten\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eKeine neue Autorisierung automatisch erstellen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Testbedingung\"\u003eRPC-Fehler bei der Belegabfrage\u003c/td\u003e\n\u003ctd data-label=\"Erwartetes Verhalten\"\u003eTransaktionshash speichern und erneut abfragen\u003c/td\u003e\n\u003ctd data-label=\"Zusätzliche Prüfung\"\u003eNicht vorschnell als Zahlungsfehler einstufen\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eIm grundlegenden Autorisierungsablauf wird der Handler vor der Abwicklung ausgeführt. Eine fehlgeschlagene Abwicklung macht externe Vorgänge nicht rückgängig. Beginnen Sie wie in diesem Beispiel mit Abfragen ohne Seiteneffekte.\u003c/p\u003e\n\u003cp\u003eDer Versand von E-Mails oder das Anlegen externer Aufträge erfordert eine separate Konzeption. Speichern Sie Zahlungs- und Vorgangsstatus gemeinsam. Legen Sie fest, welche Schritte bei einem Fehler erneut ausgeführt werden, um doppelte Vorgänge zu reduzieren.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#wiederherstellung-bei-antwortverlust-nach-der-abwicklung\" class=\"anchor\" id=\"wiederherstellung-bei-antwortverlust-nach-der-abwicklung\"\u003e\u003c/a\u003eWiederherstellung bei Antwortverlust nach der Abwicklung\u003c/h2\u003e\n\u003cp\u003eSpeichern Sie den Abschluss der Zahlung und den Abschluss der Inhaltsauslieferung als getrennte Zustände. Die Zahlung kann bereits abgeschlossen sein, während die Verbindung für die Antwort abbricht. Die Grundlage für den Umgang mit solchen Fällen bildet die \u003ca href=\"https://docs.x402.org/extensions/payment-identifier\"\u003eDokumentation der Payment-Identifier-Erweiterung\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eDie Eigenschaft, dass eine erneute Anfrage für denselben Vorgang nicht zu einer doppelten Verarbeitung führt, heißt Idempotenz. \u003ccode\u003epayment-identifier\u003c/code\u003e stellt dafür eine Zahlungskennung bereit. Diese Funktion ist nicht allein durch das Hinzufügen der Kennung vollständig umgesetzt.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#vergleich-von-doppelzahlungen-und-erneuten-%C3%BCbertragungen\" class=\"anchor\" id=\"vergleich-von-doppelzahlungen-und-erneuten-übertragungen\"\u003e\u003c/a\u003eVergleich von Doppelzahlungen und erneuten Übertragungen\u003c/h3\u003e\n\u003cp\u003eDer Schutz vor Wiederverwendung derselben Signatur muss von der Verhinderung doppelter Aufträge unterschieden werden. EIP-3009 verhindert, dass ein bereits verwendeter Autorisierungs-Nonce erneut genutzt wird. Dieses Verhalten ist in der \u003ca href=\"https://eips.ethereum.org/EIPS/eip-3009\"\u003eERC-3009-Spezifikation\u003c/a\u003e definiert.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSituation\u003c/th\u003e\n\u003cth\u003eAus Sicht der Onchain-Autorisierung\u003c/th\u003e\n\u003cth\u003eAus Sicht des API-Betriebs\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situation\"\u003eDieselbe Autorisierung erneut abwickeln\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht der Onchain-Autorisierung\"\u003ePrüfung auf bereits verwendeten Nonce\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht des API-Betriebs\"\u003eBestehendes Ergebnis muss abgefragt werden\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situation\"\u003eNeue Autorisierung für denselben Auftrag erstellen\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht der Onchain-Autorisierung\"\u003eKann als separate Autorisierung verarbeitet werden\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht des API-Betriebs\"\u003eDoppelzahlungen müssen verhindert werden\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situation\"\u003eAntwortverlust nach erfolgreicher Abwicklung\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht der Onchain-Autorisierung\"\u003eVermögensübertragung kann abgeschlossen sein\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht des API-Betriebs\"\u003eInhalte müssen erneut ausgeliefert werden\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Situation\"\u003eZeitüberschreitung nach Abwicklungsanfrage\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht der Onchain-Autorisierung\"\u003eErgebnis ist noch unklar\u003c/td\u003e\n\u003ctd data-label=\"Aus Sicht des API-Betriebs\"\u003eAusstehender Zustand und Prüfung der Abwicklung erforderlich\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eDas folgende Verfahren ist ein Entwurf zur Anbindung der offiziellen Erweiterung an einen Datenspeicher im Produktivbetrieb. Es ist im obigen Minimalcode nicht enthalten. Ergänzen Sie für den Produktivbetrieb einen persistenten Speicher und eine Steuerung gleichzeitiger Anfragen.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eDeklarieren Sie auf dem Server die Unterstützung der Erweiterung \u003ccode\u003epayment-identifier\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eBewahren Sie auf dem Client die Kennung der logischen Anfrage auf.\u003c/li\u003e\n\u003cli\u003eVerknüpfen Sie die Kennung auf dem Server mit dem Zahler und dem Anfrageinhalt.\u003c/li\u003e\n\u003cli\u003eSpeichern Sie den Bearbeitungsstatus atomar, um eine gleichzeitige Ausführung zu verhindern.\u003c/li\u003e\n\u003cli\u003eSpeichern Sie nach erfolgreicher Abwicklung den Transaktionsnachweis und das Antwortergebnis.\u003c/li\u003e\n\u003cli\u003eGeben Sie bei einer erneuten Anfrage mit denselben Berechtigungen und Inhalten das gespeicherte Ergebnis zurück.\u003c/li\u003e\n\u003cli\u003ePrüfen Sie bei unklarem Abwicklungsergebnis zuerst die bestehende Autorisierung.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eEine Zahlungskennung ist weder ein Passwort noch ein Zugriffstoken. Geben Sie kostenpflichtige Cache-Inhalte nicht an eine Anfrage zurück, die lediglich die Kennung kennt. Prüfen Sie auch, ob sie von einem anderen Nutzer oder mit einem anderen Anfrage-Body wiederverwendet wird.\u003c/p\u003e\n\u003cp\u003eHalten Sie in den Betriebsaufzeichnungen Chain, Transaktionshash und Log-Position gemeinsam fest. Verknüpfen Sie diesen Datensatz mit dem Auftrag, um eine Wiederverwendung für andere Aufträge zu verhindern. Eine Übereinstimmung bei \u003ccode\u003eTransfer\u003c/code\u003e allein weist noch keine Auftragszuordnung nach.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#h%C3%A4ufige-fehler-bei-der-zahlungsimplementierung\" class=\"anchor\" id=\"häufige-fehler-bei-der-zahlungsimplementierung\"\u003e\u003c/a\u003eHäufige Fehler bei der Zahlungsimplementierung\u003c/h2\u003e\n\u003cp\u003eWer Versionsfelder und Erfolgssignale verwechselt, kann den Zahlungsstatus falsch beurteilen. Nutzen Sie die folgende Tabelle für die Prüfung vor der Bereitstellung. Die Versionsunterschiede richten sich nach dem \u003ca href=\"https://docs.x402.org/guides/migration-v1-to-v2\"\u003ex402-Migrationsleitfaden\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eHäufiger Fehler\u003c/th\u003e\n\u003cth\u003eKorrekte Vorgehensweise\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003e\n\u003ccode\u003eextra.version: \"2\"\u003c/code\u003e als x402-Version interpretieren\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eProtokollversion anhand von \u003ccode\u003ex402Version\u003c/code\u003e prüfen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003e\n\u003ccode\u003emaxAmountRequired\u003c/code\u003e in v2 verwenden\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eFür den Betrag in den Zahlungsbedingungen \u003ccode\u003eamount\u003c/code\u003e verwenden\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003eEigenmächtig einen Header \u003ccode\u003eX-PAYMENT-REQUIRED\u003c/code\u003e erstellen\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eIn v1 den Body, in v2 \u003ccode\u003ePAYMENT-REQUIRED\u003c/code\u003e verwenden\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003e\n\u003ccode\u003eisValid: true\u003c/code\u003e als abgeschlossenen Zahlungseingang behandeln\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eErgebnis von \u003ccode\u003e/settle\u003c/code\u003e separat prüfen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003eDas oberste \u003ccode\u003eto\u003c/code\u003e-Feld der Transaktion als USDC-Empfänger behandeln\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eUSDC \u003ccode\u003eTransfer.to\u003c/code\u003e prüfen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003eAnnehmen, dass Signierer und Transaktionsabsender identisch sind\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eDen Zahler der Autorisierung mit \u003ccode\u003eTransfer.from\u003c/code\u003e vergleichen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003eTestnetzeingänge zum Umsatz addieren\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eGetrennte Bücher für Mainnet und Testnetz führen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003eBei jeder Zeitüberschreitung eine neue Zahlung erstellen\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003eZuerst bestehenden Auftrag und Autorisierungsstatus wiederherstellen\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Häufiger Fehler\"\u003eSDK-Paketversion und Protokollversion gleichsetzen\u003c/td\u003e\n\u003ctd data-label=\"Korrekte Vorgehensweise\"\u003ePaketversion und \u003ccode\u003ex402Version\u003c/code\u003e getrennt verwalten\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eAuch die Domain-Informationen einer USDC-Signatur enthalten eine Versionszeichenfolge. Dieser Wert erfüllt einen anderen Zweck als die x402-Protokollversion. Die Struktur der Signatur-Domain finden Sie in der \u003ca href=\"https://eips.ethereum.org/EIPS/eip-3009\"\u003eERC-3009-Spezifikation\u003c/a\u003e.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#sicherheitspr%C3%BCfung-und-vertrauensgrenzen-externer-dienste\" class=\"anchor\" id=\"sicherheitsprüfung-und-vertrauensgrenzen-externer-dienste\"\u003e\u003c/a\u003eSicherheitsprüfung und Vertrauensgrenzen externer Dienste\u003c/h2\u003e\n\u003cp\u003eSteuern Sie die Beurteilung des Zahlungserfolgs auf dem Server. Auch der Antwort eines externen Facilitators wird ausdrücklich Vertrauen entgegengebracht. Die Architektur, die auch einen Eigenbetrieb ermöglicht, ist in der \u003ca href=\"https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md\"\u003eFacilitator-Dokumentation\u003c/a\u003e beschrieben.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eGeben Sie Inhalte nicht aufgrund einer Erfolgsmeldung des Clients frei.\u003c/li\u003e\n\u003cli\u003eVergleichen Sie Chain, Token, Betrag und Empfänger mit den Angaben des Servers.\u003c/li\u003e\n\u003cli\u003eSchreiben Sie private Schlüssel und Seed-Phrasen nicht in Logs.\u003c/li\u003e\n\u003cli\u003eSchließen Sie auch vollständige Autorisierungssignaturen aus allgemeinen Zugriffslogs aus.\u003c/li\u003e\n\u003cli\u003eBegrenzen Sie die Größe der Zahlungsheader und die Bearbeitungszeit von Anfragen.\u003c/li\u003e\n\u003cli\u003ePrüfen Sie, dass kostenpflichtige Antworten nicht in gemeinsam genutzten Caches verbleiben.\u003c/li\u003e\n\u003cli\u003eBewahren Sie Testschlüssel und Produktivschlüssel getrennt auf.\u003c/li\u003e\n\u003cli\u003eSchaffen Sie bei einem Facilitator-Ausfall keinen Umgehungsweg ohne Zahlung.\u003c/li\u003e\n\u003cli\u003eTesten Sie den Ablauf von Autorisierungen und doppelte Anfragen tatsächlich.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBei den festgeschriebenen Abhängigkeiten dieser Übung bestehen weiterhin Warnungen aus der Sicherheitsprüfung. \u003ccode\u003enpm audit\u003c/code\u003e meldete einen Sicherheitshinweis zu zod. Einzelheiten finden Sie im \u003ca href=\"https://github.com/advisories/GHSA-mrhx-c7xc-m3w5\"\u003eGitHub-Sicherheitshinweis\u003c/a\u003e.\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u003cspan\u003enpm\u003c/span\u003e\u003cspan\u003e audit\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003ePrüfen Sie vor dem Produktiveinsatz die SDK-Kompatibilität der korrigierten Version. Ein erzwungener Wechsel der Hauptversion kann das Verhalten verändern. Verwenden Sie diese Übung nicht als bereits sicherheitsgeprüfte Bereitstellungskonfiguration.\u003c/p\u003e\n\u003ch3\u003e\n\u003ca href=\"#vergleich-von-eigenem-server-und-cloudflare-gateway\" class=\"anchor\" id=\"vergleich-von-eigenem-server-und-cloudflare-gateway\"\u003e\u003c/a\u003eVergleich von eigenem Server und Cloudflare Gateway\u003c/h3\u003e\n\u003cp\u003eBei Verwendung von Cloudflare Gateway ändert sich das Prüfverfahren des Ursprungsservers. Die Dokumentation vom 30. September 2026 nennt ausdrücklich die Verwendung von x402 v2. Die folgende Gegenüberstellung basiert auf der \u003ca href=\"https://developers.cloudflare.com/monetization-gateway/x402/\"\u003eCloudflare-x402-Dokumentation\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eMerkmal\u003c/th\u003e\n\u003cth\u003eExpress-Verfahren dieses Artikels\u003c/th\u003e\n\u003cth\u003eCloudflare Monetization Gateway\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eVerarbeitung der Client-Zahlung\u003c/td\u003e\n\u003ctd data-label=\"Express-Verfahren dieses Artikels\"\u003eExpress-Middleware\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eGateway\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003ePrüfpunkt des Ursprungsservers\u003c/td\u003e\n\u003ctd data-label=\"Express-Verfahren dieses Artikels\"\u003eAnbindung an den ausgewählten Facilitator\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003ePrüfung des JWT in \u003ccode\u003ePAYMENT-CONTEXT\u003c/code\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eÜbermittlung des Abwicklungsergebnisses\u003c/td\u003e\n\u003ctd data-label=\"Express-Verfahren dieses Artikels\"\u003e\n\u003ccode\u003ePAYMENT-RESPONSE\u003c/code\u003e der Middleware\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eGateway erstellt den Abwicklungsbeleg\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Merkmal\"\u003eZusätzlich zu prüfen\u003c/td\u003e\n\u003ctd data-label=\"Express-Verfahren dieses Artikels\"\u003eUnterstützte Chains und Authentifizierung des Facilitators\u003c/td\u003e\n\u003ctd data-label=\"Cloudflare Monetization Gateway\"\u003eJWT-Signaturprüfung und Schutz des Ursprungszugriffs\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003e\u003ccode\u003ePAYMENT-CONTEXT\u003c/code\u003e ist ein Header zwischen Gateway und Ursprungsserver. Er ist nicht der Signaturheader eines gewöhnlichen x402-Clients. Richten Sie die Prüfung auf dem Ursprungsserver nach der \u003ca href=\"https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/\"\u003eCloudflare-Dokumentation zu Payment validation\u003c/a\u003e aus.\u003c/p\u003e\n\u003cp\u003eAuch hinter dem Gateway darf das JWT nicht nur dekodiert werden. Prüfen Sie die Signatur mit dem in der Dokumentation angegebenen Schlüssel. Sperren Sie kostenpflichtige Inhalte, wenn der Header fehlt oder die Prüfung fehlschlägt.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#tats%C3%A4chliche-nutzung-und-abwicklungsaufzeichnungen-unterscheiden\" class=\"anchor\" id=\"tatsächliche-nutzung-und-abwicklungsaufzeichnungen-unterscheiden\"\u003e\u003c/a\u003eTatsächliche Nutzung und Abwicklungsaufzeichnungen unterscheiden\u003c/h2\u003e\n\u003cp\u003eDie Anzahl der Onchain-Überweisungen allein belegt nicht den Konsum von Inhalten. Verknüpfen Sie für Betriebskennzahlen die Abwicklung mit der Auslieferung der Antwort. Dies ist ein Gestaltungsvorschlag auf Grundlage des Zahlungsablaufs und des Verhaltens bei erneuter Übertragung.\u003c/p\u003e\n\u003cdiv class=\"overflow-x-auto\"\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eAufzeichnung\u003c/th\u003e\n\u003cth\u003eWelche Frage sie beantwortet\u003c/th\u003e\n\u003cth\u003eZusätzlich benötigte Aufzeichnung\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aufzeichnung\"\u003e402-Antwort\u003c/td\u003e\n\u003ctd data-label=\"Welche Frage sie beantwortet\"\u003eWie oft Zahlungsbedingungen angefordert wurden\u003c/td\u003e\n\u003ctd data-label=\"Zusätzlich benötigte Aufzeichnung\"\u003eOb tatsächlich gezahlt wurde\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aufzeichnung\"\u003eErfolgreiche Prüfung\u003c/td\u003e\n\u003ctd data-label=\"Welche Frage sie beantwortet\"\u003eOb die Autorisierung gültig war\u003c/td\u003e\n\u003ctd data-label=\"Zusätzlich benötigte Aufzeichnung\"\u003eAbwicklungsergebnis\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aufzeichnung\"\u003eUSDC-Transfer\u003c/td\u003e\n\u003ctd data-label=\"Welche Frage sie beantwortet\"\u003eOb Vermögenswerte übertragen wurden\u003c/td\u003e\n\u003ctd data-label=\"Zusätzlich benötigte Aufzeichnung\"\u003eAuftragszuordnung\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aufzeichnung\"\u003eAbgeschlossene Abwicklung pro Auftrag\u003c/td\u003e\n\u003ctd data-label=\"Welche Frage sie beantwortet\"\u003eOb eine kostenpflichtige Anfrage bezahlt wurde\u003c/td\u003e\n\u003ctd data-label=\"Zusätzlich benötigte Aufzeichnung\"\u003eAuslieferungsstatus der Antwort\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd data-label=\"Aufzeichnung\"\u003eAufzeichnung der erneuten Auslieferung\u003c/td\u003e\n\u003ctd data-label=\"Welche Frage sie beantwortet\"\u003eOb eine bereits bezahlte Anfrage wiederhergestellt wurde\u003c/td\u003e\n\u003ctd data-label=\"Zusätzlich benötigte Aufzeichnung\"\u003eKennung zur Unterscheidung von neuen Zahlungen\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003cp\u003eKennzeichnen Sie Testanfragen getrennt von der tatsächlichen Nutzung. Markieren Sie auch Wiederholungen desselben Auftrags gesondert. Das Transaktionsvolumen allein darf nicht als API-Nachfrage oder Umsatzgarantie dargestellt werden.\u003c/p\u003e\n\u003ch2\u003e\n\u003ca href=\"#umstellung-auf-base-mainnet\" class=\"anchor\" id=\"umstellung-auf-base-mainnet\"\u003e\u003c/a\u003eUmstellung auf Base Mainnet\u003c/h2\u003e\n\u003cp\u003eZiehen Sie das Mainnet erst in Betracht, nachdem Sie die Erfolgs- und Fehlerabläufe im Testnetz geprüft haben. Die Umstellung ist nicht mit dem Ändern der Netzwerkzeichenfolge abgeschlossen. Das grundlegende Verfahren folgt dem \u003ca href=\"https://docs.x402.org/getting-started/quickstart-for-sellers#running-on-mainnet\"\u003eoffiziellen Verkäuferleitfaden\u003c/a\u003e.\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ePrüfen Sie, ob der ausgewählte Facilitator Base Mainnet unterstützt.\u003c/li\u003e\n\u003cli\u003ePrüfen Sie unter \u003ccode\u003e/supported\u003c/code\u003e die Unterstützung von v2, \u003ccode\u003eexact\u003c/code\u003e und \u003ccode\u003eeip155:8453\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eRichten Sie die vom Anbieter verlangte Authentifizierung und die Nutzungsbedingungen ein.\u003c/li\u003e\n\u003cli\u003eÄndern Sie das Netzwerk auf Server und Client gemeinsam.\u003c/li\u003e\n\u003cli\u003eÄndern Sie die erlaubte USDC-Adresse des Clients auf die Mainnet-Adresse.\u003c/li\u003e\n\u003cli\u003eGleichen Sie den Betrag der 402-Antwort und die tatsächliche Empfängeradresse erneut ab.\u003c/li\u003e\n\u003cli\u003eBinden Sie den Speicher für doppelte Anfragen und die Verfahren zur Fehlerwiederherstellung an.\u003c/li\u003e\n\u003cli\u003eSchließen Sie die Sicherheitsprüfung der Produktivabhängigkeiten ab.\u003c/li\u003e\n\u003cli\u003ePrüfen Sie mit dem festgelegten kleinen Betrag die tatsächliche Übertragung und Inhaltsauslieferung.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eMulti-Chain-Unterstützung bedeutet nicht, dass alle Kombinationen unterstützt werden. Prüfen Sie den Unterstützungsumfang von SDK und Facilitator gemeinsam. Maßgeblich ist die \u003ca href=\"https://docs.x402.org/core-concepts/network-and-token-support\"\u003eDokumentation zur Netzwerk- und Token-Unterstützung\u003c/a\u003e.\u003c/p\u003e\n","tags":["Stablecoin","KI-Agent","KI Entwicklung","Content Monetarisierung","Entwicklungstools"],"faqs":[{"question":"Worin unterscheidet sich x402 von der üblichen Überprüfung eines USDC-Zahlungseingangs?","answer":"Im Rahmen einer HTTP-Anfrage werden die Zahlungsbedingungen übermittelt, und die Anfrage wird mit einer signierten Zahlungsautorisierung erneut gesendet. Anders als beim nachträglichen Abgleich von Zahlungseingängen wird der Zahlungsvorgang mit der Anforderung kostenpflichtiger Ressourcen verknüpft."},{"question":"Welche Zahlungsheader verwendet x402 v2?","answer":"Die Zahlungsbedingungen werden über PAYMENT-REQUIRED und die Zahlungs-Payload über PAYMENT-SIGNATURE übermittelt. Das Ergebnis der Zahlungsabwicklung wird über PAYMENT-RESPONSE übermittelt."},{"question":"Gibt es in v1 den Header X-PAYMENT-REQUIRED?","answer":"Laut der offiziellen HTTP-v1-Spezifikation werden die anfänglichen Zahlungsbedingungen im JSON-Antworttext übermittelt. Für die Zahlungs-Payload und das Ergebnis der Zahlungsabwicklung werden X-PAYMENT bzw. X-PAYMENT-RESPONSE verwendet."},{"question":"Ist die Zahlung abgeschlossen, wenn /verify erfolgreich ist?","answer":"Ein erfolgreicher Aufruf von /verify bedeutet, dass die Zahlungsautorisierung gültig ist. In dieser Übung muss das erfolgreiche Ergebnis von /settle gesondert geprüft werden."},{"question":"Lässt sich Test-USDC auf Base Sepolia als tatsächliche Einnahme betrachten?","answer":"Circle weist ausdrücklich darauf hin, dass Testnet-USDC keinen finanziellen Wert hat. Erfassen Sie Zahlungsabwicklungen im Testnet getrennt von tatsächlichen Umsätzen."},{"question":"Muss auf dem Empfängerserver ein privater Schlüssel hinterlegt werden?","answer":"Auf dem Empfängerserver dieses Beispiels wird nur die öffentliche Empfängeradresse konfiguriert. Der private Schlüssel für die Zahlungsautorisierung wird vom Zahlungsclient eingelesen."},{"question":"Welchen Wert hat amount für 0.001 USDC?","answer":"Berücksichtigt man die 6 Nachkommastellen von USDC, ergibt sich in der kleinsten Einheit der Wert 1000. In den Zahlungsbedingungen von v2 wird die Zeichenfolge \"1000\" verwendet."},{"question":"Ist der USDC-Eingang ebenfalls bestätigt, wenn der Transaktionsbeleg einen Erfolg ausweist?","answer":"Der Erfolgsstatus der Transaktion allein reicht nicht aus. Gleichen Sie Zahler, Empfänger und Betrag anhand des Transfer-Ereignisses des offiziellen USDC-Smart-Contracts ab."},{"question":"Kann dieselbe Zahlungsanfrage gefahrlos erneut gesendet werden?","answer":"Die Verhinderung der Wiederverwendung derselben Autorisierungs-Nonce und die Vermeidung doppelter Bestellungen sind zwei verschiedene Dinge. Prüfen Sie vor einem erneuten Versuch den Status der bestehenden Zahlung und implementieren Sie eine idempotente Verarbeitung pro Bestellung."},{"question":"Kann ich einfach erneut bezahlen, wenn PAYMENT-RESPONSE fehlt?","answer":"Bei einer verloren gegangenen Antwort oder einer Zeitüberschreitung kann das Ergebnis der Zahlungsabwicklung unklar sein. Erstellen Sie nicht gleich eine neue Autorisierung, sondern prüfen Sie den Abwicklungsstatus der bestehenden Anfrage."},{"question":"Muss bei x402 der Facilitator eines bestimmten Unternehmens verwendet werden?","answer":"Die offizielle Architektur erlaubt sowohl die Nutzung eines externen Facilitators als auch den Eigenbetrieb. Prüfen Sie, ob die gewählte Implementierung die benötigte Protokollversion, Zahlungsmethode und Blockchain unterstützt."},{"question":"Werden auch die Ausgaben eines KI-Agenten automatisch begrenzt?","answer":"Dieses Beispiel begrenzt nur die Zahlungsbedingungen pro Anfrage. Verwalten Sie die durch wiederholte Aufrufe entstehenden kumulierten Ausgaben mit einer separaten Budgetrichtlinie."},{"question":"Ist Cloudflare PAYMENT-CONTEXT ein Standardheader für Zahlungssignaturen?","answer":"PAYMENT-CONTEXT ist ein JWT, das vom Gateway an den Ursprungsserver übermittelt wird. Es dient einem anderen Zweck als die PAYMENT-SIGNATURE des Clients."},{"question":"Kann ich das Beispiel direkt im Mainnet bereitstellen?","answer":"Dieser Code ist eine Minimalkonfiguration für Testzwecke. Prüfen Sie vor der Bereitstellung in der Produktionsumgebung die Sicherheitswarnungen zu Abhängigkeiten, die Verarbeitung doppelter Anfragen, die Authentifizierung des Facilitators und die tatsächliche Abrechnung."}],"sources":[{"url":"https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md","title":"x402-Protokollspezifikation v2","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/specs/transports-v1/http.md","title":"x402 HTTP-Transport v1","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/http.md","title":"x402 HTTP-Transport v2","type":"source"},{"url":"https://docs.x402.org/guides/migration-v1-to-v2","title":"x402-Migrationsleitfaden: Von V1 zu V2","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/docs/core-concepts/facilitator.md","title":"x402 Facilitator: Rolle und Verantwortlichkeiten","type":"source"},{"url":"https://docs.x402.org/getting-started/quickstart-for-sellers","title":"x402-Schnellstart für Verkäufer","type":"source"},{"url":"https://docs.x402.org/getting-started/quickstart-for-buyers","title":"x402-Schnellstart für Käufer","type":"source"},{"url":"https://github.com/x402-foundation/x402/tree/main/examples/typescript/clients/fetch","title":"Offizielles x402-Beispiel für einen TypeScript-Client mit fetch","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/typescript/packages/http/express/src/index.ts","title":"Implementierung einer Express-Middleware für x402","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/typescript/packages/core/src/client/x402Client.ts","title":"Auswahl von Zahlungsbedingungen und Implementierung von Richtlinien für x402Client","type":"source"},{"url":"https://github.com/x402-foundation/x402/blob/main/typescript/packages/mechanisms/evm/src/exact/server/scheme.ts","title":"Implementierung der serverseitigen Preisumrechnung für x402 ExactEvmScheme","type":"source"},{"url":"https://developers.circle.com/stablecoins/usdc-contract-addresses","title":"Contract-Adressen für Circle USDC","type":"data_point"},{"url":"https://docs.base.org/get-started/connect-to-base","title":"Netzwerkinformationen zu Base Mainnet und Base Sepolia","type":"data_point"},{"url":"https://faucet.circle.com/","title":"Circle Testnet Faucet","type":"source"},{"url":"https://viem.sh/docs/actions/public/getTransactionReceipt","title":"viem getTransactionReceipt","type":"source"},{"url":"https://viem.sh/docs/contract/parseEventLogs","title":"viem parseEventLogs","type":"source"},{"url":"https://eips.ethereum.org/EIPS/eip-20","title":"ERC-20-Tokenstandard","type":"source"},{"url":"https://eips.ethereum.org/EIPS/eip-3009","title":"ERC-3009 Übertragung mit Autorisierung","type":"source"},{"url":"https://docs.x402.org/extensions/payment-identifier","title":"x402 Payment-Identifier: Idempotenz-Erweiterung","type":"source"},{"url":"https://developers.cloudflare.com/monetization-gateway/x402/","title":"Cloudflare Monetization Gateway: x402-Protokoll","type":"source"},{"url":"https://developers.cloudflare.com/monetization-gateway/configuration/payment-validation/","title":"Cloudflare Monetization Gateway: Zahlungsvalidierung","type":"source"},{"url":"https://docs.x402.org/core-concepts/network-and-token-support","title":"x402: Unterstützung für Netzwerke und Token","type":"source"},{"url":"https://github.com/advisories/GHSA-mrhx-c7xc-m3w5","title":"GitHub-Sicherheitshinweis: Erschöpfung des Arbeitsspeichers durch die Validierung großer Sammlungen mit Zod","type":"source"}],"images":[{"id":2199,"url":"https://injoys.com/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzM4MDcsInB1ciI6ImJsb2JfaWQifX0=--49c502fd8da16158a617c3586dfa81ced4bc95df/ai-f0ae2b5c.webp","is_representative":true,"generation_method":"ai_photo","license":"ai_generated","mime_type":"image/webp","width":1536,"height":1024,"translations":{"ko":{"alt":"짙은 회색 스웨터를 입은 남성이 서버 랙 선반에 놓인 태블릿 화면을 살펴보고 있다.","caption":"메인넷으로 전환하기 전에 테스트 환경에서 x402 결제 연동을 검증하세요.","description":null},"en":{"alt":"A man in a dark gray sweater examines a tablet resting on a server rack shelf.","caption":"Validate the x402 payment integration in a test environment before switching to mainnet.","description":null},"ja":{"alt":"濃いグレーのセーターを着た男性が、サーバーラックの棚に置かれたタブレットを確認している。","caption":"メインネットへ移行する前に、テスト環境でx402の決済連携を検証しましょう。","description":null},"es":{"alt":"Un hombre con un suéter gris oscuro revisa una tableta sobre la bandeja de un rack de servidores.","caption":"Valida la integración de pagos x402 en un entorno de prueba antes de pasar a la red principal.","description":null},"id":{"alt":"Seorang pria bersweater abu-abu gelap memeriksa tablet di atas ambalan rak server.","caption":"Validasi integrasi pembayaran x402 di lingkungan uji sebelum beralih ke mainnet.","description":null},"pt":{"alt":"Um homem de suéter cinza-escuro examina um tablet apoiado na prateleira de um rack de servidores.","caption":"Valide a integração de pagamentos x402 em um ambiente de teste antes de migrar para a rede principal.","description":null},"zh-hant":{"alt":"一名穿著深灰色毛衣的男子正在查看伺服器機架層板上的平板電腦。","caption":"切換至主網前，先在測試環境中驗證 x402 支付整合。","description":null},"de":{"alt":"Ein Mann im dunkelgrauen Pullover prüft ein Tablet auf der Ablage eines Serverracks.","caption":"Prüfen Sie die x402-Zahlungsintegration in einer Testumgebung, bevor Sie ins Mainnet wechseln.","description":null}}},{"id":2200,"url":"https://injoys.com/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzM4MTMsInB1ciI6ImJsb2JfaWQifX0=--4e70727f132519277c68d1c6279d95585a936549/ai-3dbd1c62.webp","is_representative":false,"generation_method":"ai_semi","license":"ai_generated","mime_type":"image/webp","width":1536,"height":1024,"translations":{"ko":{"alt":"창가에서 여성이 평평하게 펼친 노트북으로 입력하고 있으며, 화면에는 목록과 두 경로가 합쳐지는 흐름도가 보인다.","caption":"중복 요청 복구를 시험해 결제 재시도가 이중 정산으로 이어지지 않는지 확인하세요.","description":null},"en":{"alt":"A woman types on a laptop opened flat, with a list and two paths converging on one endpoint on its screen.","caption":"Test duplicate-request recovery to ensure payment retries do not cause a second settlement.","description":null},"ja":{"alt":"窓辺で女性が平らに開いたノートパソコンを操作し、画面には一覧と2本の経路が合流するフロー図が表示されている。","caption":"重複リクエストの復旧をテストし、決済の再試行で二重精算が起きないことを確認しましょう。","description":null},"es":{"alt":"Una mujer teclea en un portátil abierto en plano; la pantalla muestra una lista y dos rutas que convergen.","caption":"Prueba la recuperación de solicitudes duplicadas para evitar una segunda liquidación al reintentar el pago.","description":null},"id":{"alt":"Seorang perempuan mengetik di laptop yang dibuka rata, dengan daftar dan diagram dua jalur yang menyatu di layar.","caption":"Uji pemulihan permintaan duplikat untuk memastikan percobaan ulang pembayaran tidak memicu penyelesaian ganda.","description":null},"pt":{"alt":"Uma mulher digita num notebook aberto na horizontal, com uma lista e duas rotas convergentes na tela.","caption":"Teste a recuperação de solicitações duplicadas para garantir que novas tentativas de pagamento não gerem liquidação dupla.","description":null},"zh-hant":{"alt":"一名女子在窗邊操作完全攤平的筆記型電腦，螢幕顯示清單及兩條路徑匯合的流程圖。","caption":"測試重複請求的復原流程，確認付款重試不會造成重複結算。","description":null},"de":{"alt":"Eine Frau tippt auf einem flach aufgeklappten Laptop; das Display zeigt eine Liste und zwei zusammenlaufende Pfade.","caption":"Testen Sie die Wiederherstellung bei doppelten Anfragen, damit Zahlungswiederholungen keine zweite Abrechnung auslösen.","description":null}}}],"published_at":"2026-10-28T19:20:55+09:00","updated_at":"2026-10-28T19:20:55+09:00","license":"cc_by","translation_status":"reviewed","available_locales":["ko","en","ja","es"],"data_locales":["ko","en","ja","es","id","pt","zh-hant","de"],"url":"https://injoys.com/en/articles/x402-payments-2026-v2-base-usdc-settlement-guide"}