@emdash-cms/x402 套件為 Cloudflare 上的任何 Astro 網站添加 x402 支付協定支援。它作為獨立的 Astro 整合運行,在使用 EmDash 時可以與 EmDash 的 CMS 欄位配合實現按頁定價。
x402 是一個 HTTP 原生支付協定。當客戶端請求付費資源而未付款時,伺服器會返回 402 Payment Required 回應和機器可讀的支付指令。理解 x402 的代理和瀏覽器可以自動完成支付並重試請求。
何時使用
最常見的使用場景是僅針對機器人模式:向 AI 代理和爬蟲收取內容存取費用,同時讓人類訪客免費閱讀。這使用 Cloudflare Bot Management 來區分機器人和人類。
你也可以對所有訪客強制收費,或在不強制的情況下檢查支付標頭(條件渲染)。
安裝
使用你的套件管理器安裝此套件:
pnpm
pnpm add @emdash-cms/x402 npm
npm install @emdash-cms/x402 yarn
yarn add @emdash-cms/x402 設定
將整合添加到你的 Astro 設定中:
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,
}),
],
});
添加型別參考,讓 TypeScript 知道 Astro.locals.x402:
/// <reference types="@emdash-cms/x402/locals" />
基本用法
整合在 Astro.locals.x402 上放置了一個強制器。在頁面前置程式碼中呼叫 enforce() 來保護付費內容:
---
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>
enforce() 方法返回以下之一:
Response(402) — 客戶端需要付款。直接返回它。EnforceResult— 請求應該繼續。內容已付費,或強制被跳過(botOnly 模式下的人類)。
僅針對機器人模式
當 botOnly 為 true 時,整合會讀取 request.cf.botManagement.score 來分類請求:
- 分數低於閾值(預設 30)-> 被視為機器人,強制付款
- 分數達到或高於閾值 -> 被視為人類,跳過強制
- 無機器人管理資料(本地開發、非 CF 部署)-> 被視為人類
EnforceResult 包含一個 skipped 旗標,讓你可以區分「不需要付款」和「已付款」:
---
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)
---
使用 EmDash 實現按頁定價
使用 EmDash 時,向集合添加一個常規的 number 欄位用於按頁定價,並在請求時讀取它:
---
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>
檢查支付而不強制
使用 hasPayment() 在不驗證或強制的情況下檢查請求是否包含支付標頭。這對條件渲染很有用 — 向付費和未付費訪客展示不同內容:
---
const { x402 } = Astro.locals;
const hasPaid = x402.hasPayment(Astro.request);
---
{hasPaid ? (
<p>Full premium content here.</p>
) : (
<p>Subscribe for the full article.</p>
)}
設定參考
| 選項 | 類型 | 預設值 | 描述 |
|---|---|---|---|
payTo | string | 必需 | 目標錢包地址 |
network | string | 必需 | CAIP-2 網路標識符(例如 eip155:8453) |
defaultPrice | Price | — | 預設價格,可按頁覆蓋 |
facilitatorUrl | string | https://x402.org/facilitator | 支付促進器 URL |
scheme | string | "exact" | 支付方案 |
maxTimeoutSeconds | number | 60 | 支付簽名的最大逾時時間 |
evm | boolean | true | 啟用 EVM 鏈支援 |
svm | boolean | false | 啟用 Solana 鏈支援(需要 @x402/svm) |
botOnly | boolean | false | 僅對機器人強制收費 |
botScoreThreshold | number | 30 | 機器人分數閾值(1-99,越低越可能是機器人) |
價格格式
價格可以用多種格式指定:
- 美元字串 —
"$0.10"($前綴被去除,值按原樣傳遞) - 數字字串 —
"0.10" - 數字 —
0.10 - 物件 —
{ amount: "100000", asset: "0x...", extra: {} }用於顯式資產/金額
網路標識符
網路使用 CAIP-2 格式:
| 網路 | 標識符 |
|---|---|
| Base mainnet | eip155:8453 |
| Base Sepolia | eip155:84532 |
| Ethereum | eip155:1 |
| Solana | solana:mainnet |
Enforce 選項
覆蓋特定頁面的設定預設值:
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 支援
Solana 是可選的。安裝 @x402/svm 並在設定中啟用它:
pnpm add @x402/svm
將網路設定為 Solana 標識符,如果只使用 Solana 則停用 EVM:
x402({
payTo: "YourSolanaAddress",
network: "solana:mainnet",
svm: true,
evm: false, // Disable EVM if only using Solana
});
工作原理
x402()整合註冊中介軟體,建立強制器並將其放置在Astro.locals.x402上- 設定透過 Vite 虛擬模組(
virtual:x402/config)傳遞給中介軟體 - 當呼叫
enforce()時,它檢查請求上的payment-signature標頭 - 如果不存在支付標頭,則返回
402 Payment Required回應,在PAYMENT-REQUIRED標頭中包含支付指令 - 如果存在支付標頭,則透過促進器服務進行驗證和結算
- 結算後,透過
applyHeaders()在回應上設定PAYMENT-RESPONSE標頭
資源伺服器在第一次請求時延遲初始化,並在 worker 生命週期內快取。