x402 Payments

Auf dieser Seite

Das Paket @emdash-cms/x402 fügt Unterstützung für das x402-Zahlungsprotokoll zu jeder Astro-Site auf Cloudflare hinzu. Es läuft als eigenständige Astro-Integration und lässt sich mit EmDash’s CMS-Feldern für seitenbasierte Preisgestaltung kombinieren, wenn Sie EmDash verwenden.

x402 ist ein HTTP-natives Zahlungsprotokoll. Wenn ein Client eine kostenpflichtige Ressource ohne Zahlung anfordert, antwortet der Server mit 402 Payment Required und maschinenlesbaren Zahlungsanweisungen. Agents und Browser, die x402 verstehen, können die Zahlung automatisch abschließen und die Anfrage wiederholen.

Wann dies zu verwenden ist

Der häufigste Anwendungsfall ist der Bot-Only-Modus: Berechnen Sie KI-Agenten und Scrapern den Zugriff auf Inhalte, während menschliche Besucher kostenlos lesen können. Dies nutzt Cloudflare Bot Management, um Bots von Menschen zu unterscheiden.

Sie können auch Zahlungen für alle Besucher erzwingen oder auf Zahlungsheader prüfen, ohne sie zu erzwingen (bedingte Darstellung).

Installation

Installieren Sie das Paket mit Ihrem Package Manager:

pnpm

pnpm add @emdash-cms/x402

npm

npm install @emdash-cms/x402

yarn

yarn add @emdash-cms/x402

Einrichtung

Fügen Sie die Integration zu Ihrer Astro-Konfiguration hinzu:

import { defineConfig } from "astro/config";
import { x402 } from "@emdash-cms/x402";

export default defineConfig({
	integrations: [
		x402({
			payTo: "0xYourWalletAddress",
			network: "eip155:8453", // Base mainnet
			defaultPrice: "$0.01",
			botOnly: true,
			botScoreThreshold: 30,
		}),
	],
});

Fügen Sie die Typreferenz hinzu, damit TypeScript über Astro.locals.x402 Bescheid weiß:

/// <reference types="@emdash-cms/x402/locals" />

Grundlegende Verwendung

Die Integration platziert einen Enforcer auf Astro.locals.x402. Rufen Sie enforce() in Ihrem Seiten-Frontmatter auf, um Inhalte hinter Zahlungen zu schützen:

---
const { x402 } = Astro.locals;

const result = await x402.enforce(Astro.request, {
  price: "$0.05",
  description: "Premium article",
});

// If the request has no valid payment, enforce() returns a 402 Response.
// Return it directly to send payment instructions to the client.
if (result instanceof Response) return result;

// Payment verified (or skipped in botOnly mode). Apply response headers
// so the client gets settlement proof.
x402.applyHeaders(result, Astro.response);
---

<article>
  <h1>Premium content</h1>
</article>

Die Methode enforce() gibt entweder zurück:

  • Eine Response (402) – der Client muss zahlen. Geben Sie sie direkt zurück.
  • Ein EnforceResult – die Anfrage sollte fortgesetzt werden. Der Inhalt wurde bezahlt oder die Durchsetzung wurde übersprungen (Mensch im botOnly-Modus).

Bot-Only-Modus

Wenn botOnly auf true gesetzt ist, liest die Integration request.cf.botManagement.score, um Anfragen zu klassifizieren:

  • Score unter Schwellenwert (Standard 30) -> als Bot behandelt, Zahlung erzwungen
  • Score auf oder über Schwellenwert -> als Mensch behandelt, Durchsetzung übersprungen
  • Keine Bot-Management-Daten (lokale Entwicklung, Nicht-CF-Bereitstellung) -> als Mensch behandelt

Das EnforceResult enthält ein skipped-Flag, damit Sie zwischen “musste nicht zahlen” und “bezahlt” unterscheiden können:

---
const result = await x402.enforce(Astro.request, { price: "$0.01" });
if (result instanceof Response) return result;

x402.applyHeaders(result, Astro.response);

// result.paid    — true if payment was verified
// result.skipped — true if enforcement was skipped (human in botOnly mode)
// result.payer   — wallet address of payer (if paid)
---

Seitenbasierte Preisgestaltung mit EmDash

Bei Verwendung von EmDash fügen Sie ein reguläres number-Feld zu Ihrer Sammlung für seitenbasierte Preisgestaltung hinzu und lesen Sie es zur Anfragezeit:

---
import { getEmDashEntry } from "emdash";

const { slug } = Astro.params;
const { entry } = await getEmDashEntry("posts", slug);

if (!entry) return Astro.redirect("/404");

const { x402 } = Astro.locals;

// Use the price from the CMS, falling back to a default
const result = await x402.enforce(Astro.request, {
  price: entry.data.price || "$0.01",
  description: entry.data.title,
});
if (result instanceof Response) return result;

x402.applyHeaders(result, Astro.response);
---

<article>
  <h1>{entry.data.title}</h1>
</article>

Auf Zahlung prüfen ohne Durchsetzung

Verwenden Sie hasPayment(), um zu prüfen, ob eine Anfrage Zahlungsheader enthält, ohne zu verifizieren oder durchzusetzen. Dies ist nützlich für bedingte Darstellung – um zahlenden und nicht zahlenden Besuchern unterschiedliche Inhalte zu zeigen:

---
const { x402 } = Astro.locals;

const hasPaid = x402.hasPayment(Astro.request);
---

{hasPaid ? (
  <p>Full premium content here.</p>
) : (
  <p>Subscribe for the full article.</p>
)}

Konfigurationsreferenz

OptionTypStandardBeschreibung
payTostringerforderlichZiel-Wallet-Adresse
networkstringerforderlichCAIP-2-Netzwerkidentifikator (z.B. eip155:8453)
defaultPricePriceStandardpreis, pro Seite überschreibbar
facilitatorUrlstringhttps://x402.org/facilitatorZahlungsvermittler-URL
schemestring"exact"Zahlungsschema
maxTimeoutSecondsnumber60Maximales Timeout für Zahlungssignaturen
evmbooleantrueEVM-Chain-Unterstützung aktivieren
svmbooleanfalseSolana-Chain-Unterstützung aktivieren (erfordert @x402/svm)
botOnlybooleanfalseZahlung nur für Bots erzwingen
botScoreThresholdnumber30Bot-Score-Schwellenwert (1-99, niedriger = wahrscheinlicher Bot)

Preisformat

Preise können in mehreren Formaten angegeben werden:

  • Dollar-String"$0.10" (das $-Präfix wird entfernt, Wert wird unverändert übergeben)
  • Numerischer String"0.10"
  • Zahl0.10
  • Objekt{ amount: "100000", asset: "0x...", extra: {} } für explizite Asset/Amount-Angabe

Netzwerkidentifikatoren

Netzwerke verwenden das CAIP-2-Format:

NetzwerkIdentifikator
Base mainneteip155:8453
Base Sepoliaeip155:84532
Ethereumeip155:1
Solanasolana:mainnet

Enforce-Optionen

Überschreiben Sie Konfigurationsstandards für eine bestimmte Seite:

await x402.enforce(Astro.request, {
	price: "$0.25", // Override price
	payTo: "0xDifferentWallet", // Override wallet
	network: "eip155:1", // Override network
	description: "Article: How x402 Works", // Resource description
	mimeType: "text/html", // MIME type hint
});

Solana-Unterstützung

Solana ist opt-in. Installieren Sie @x402/svm und aktivieren Sie es in der Konfiguration:

pnpm add @x402/svm

Setzen Sie das Netzwerk auf einen Solana-Identifikator und deaktivieren Sie EVM, wenn Sie nur Solana verwenden:

x402({
	payTo: "YourSolanaAddress",
	network: "solana:mainnet",
	svm: true,
	evm: false, // Disable EVM if only using Solana
});

Wie es funktioniert

  1. Die x402()-Integration registriert Middleware, die einen Enforcer erstellt und auf Astro.locals.x402 platziert
  2. Die Konfiguration wird über ein Vite-Virtual-Modul (virtual:x402/config) an die Middleware übergeben
  3. Wenn enforce() aufgerufen wird, prüft es auf einen payment-signature-Header in der Anfrage
  4. Wenn kein Zahlungsheader vorhanden ist, wird eine 402 Payment Required-Antwort mit Zahlungsanweisungen im PAYMENT-REQUIRED-Header zurückgegeben
  5. Wenn ein Zahlungsheader vorhanden ist, wird er über den Vermittlerdienst verifiziert und abgewickelt
  6. Nach der Abwicklung werden PAYMENT-RESPONSE-Header über applyHeaders() in der Antwort gesetzt

Der Ressourcen-Server wird beim ersten Request lazy initialisiert und für die Worker-Lebensdauer zwischengespeichert.