以 Cloudflare Workers、Hono 與 Vue SSR 建立的事實查核 API facade。這個 Worker 不再執行查核模型或 Cofacts pipeline,而是由 x402 付費閘門驗證付款,再透過 FACT_CHECK_CORE service binding 將請求轉送給獨立的 fact-check-core Worker。
首頁 / 的表單仍使用免費的 /api/demo 入口;需要逐次付費的整合者使用 /api/fact-check。兩個入口最後都呼叫相同的 fact-check-core,但只有 /api/fact-check 會要求 x402 付款。
/api/fact-check (GET/POST)
→ x402 PAYMENT-REQUIRED/PAYMENT-SIGNATURE
→ facilitator verify
→ FACT_CHECK_CORE service binding
→ fact-check-core POST /fact-check
→ 核心回應 <400:facilitator settle → PAYMENT-RESPONSE
↳ 核心回 >=400/fetch 失敗:直接回錯誤,不 settle
/api/demo (POST,免費)
→ Origin guard + CORS + IP rate limit
→ FACT_CHECK_CORE service binding
核心 Worker 的契約是 POST /fact-check(JSON { text, url? })與 GET /health。核心回應的本文及 X-Request-Id、Cache-Control、X-Fact-Check-Cache 等標頭會原樣轉送給呼叫端。
需要 Node.js、npm、Vite+(vp)與 Cloudflare 帳號。查核模型憑證由 fact-check-core 管理,本 repo 不需要 OpenRouter API key 或 Workers AI binding。
操作文件:
vp install
cp .dev.vars.example .dev.vars
vp run dev正式部署的公開付款設定放在 wrangler.jsonc 的 vars:PAY_TO 是公開收款錢包,
X402_NETWORK=eip155:8453(Base mainnet)、X402_PRICE=$0.05,並使用
FACILITATOR_URL=https://api.cdp.coinbase.com/platform/v2/x402。demo 的公開預設限流也在
vars 設為 RATE_LIMIT_WINDOW_MS=60000。部署前必須另外建立 CDP Secret API Key,並把 ID
與 Secret 設為 Cloudflare secrets。
本機 .dev.vars 不要提交。複製 .dev.vars.example 後會覆寫正式設定,改用不需憑證的 Base
Sepolia 公開 facilitator:
PAY_TO=0x06818A198832EcEE8Dc8f9B1492C8915921EfEAB
X402_NETWORK=eip155:84532
X402_PRICE=$0.05
FACILITATOR_URL=https://www.x402.org/facilitator
# 改用 CDP 時才填入,而且兩個值必須成對:
# CDP_API_KEY_ID=your-cdp-api-key-id
# CDP_API_KEY_SECRET=your-cdp-api-key-secret
# 只有其他 facilitator 提供固定 Bearer token 時才使用:
# FACILITATOR_AUTH_TOKEN=your-facilitator-auth-tokenwrangler.jsonc 也已設定 FACT_CHECK_CORE remote service binding。公開 x402.org facilitator
的 EVM exact scheme 僅支援 Base Sepolia;正式 Base mainnet 使用 CDP。不要把 facilitator 或 CDP
secret 放進前端程式碼。
| 方法 | 路徑 | 付款 | 用途 |
|---|---|---|---|
| GET | / |
無 | SSR 首頁與免費表單 |
| GET | /health |
無 | 回傳 {"status":"ok"} |
| GET | /api/fact-check |
x402,每次 0.05 USDC | query string 轉 JSON 後轉送 core |
| POST | /api/fact-check |
x402,每次 0.05 USDC | 轉送 JSON 至 core |
| POST | /api/demo |
免費 | 首頁使用的 core facade |
/api/fact-check 接受 text(必要,最多 10,000 個 Unicode code point)與 url(選填,公開 HTTP/HTTPS 網址,最多 2,048 個字元)。POST 必須使用 Content-Type: application/json,本文最多 128,000 bytes。輸入驗證在付款放行後執行,避免未付款請求繞過閘門。
首頁表單維持原本的免費入口:
const response = await fetch("/api/demo", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: "非學校型態學生,國中小以下目前沒有普遍補助" }),
});
const result = await response.json();/api/demo 的 POST Origin guard、正式來源 CORS 仍維持;它是唯一免費入口,預設每個 IP
每 60 秒最多一次,另有 Cloudflare RATE_LIMITER 每 10 秒 30 次的洪水層。可在
wrangler.jsonc 的 RATE_LIMIT_WINDOW_MS vars 覆寫精準冷卻時間。demo 不是付款驗證或身分驗證,
請勿把它當成付費 API 的替代入口。
付費端點使用維護中的 @x402/hono(目前 2.28.0)搭配 @x402/core、@x402/evm。
Coinbase CDP 認證使用官方 @coinbase/cdp-sdk 的 generateJwt(),為
supported、verify、settle 各自產生綁定 HTTP method、host 與 path 的短效 JWT;不會把 CDP
API Key Secret 直接送到 facilitator。
付款流程:
- 第一次呼叫不帶付款標頭,服務回 HTTP
402。 - 從
PAYMENT-REQUIRED讀取payTo、金額、網路與資產資訊。 - 使用錢包依需求簽署 x402 v2 付款,將編碼後的 v2 payload 放入
PAYMENT-SIGNATURE,或以X-PAYMENT作為同一 v2 payload 的替代標頭,再加回同一個 GET/POST 請求重試。X-PAYMENT僅是 v2 替代標頭,不代表支援 x402 v1。 - facilitator 先 verify;驗證成功後,
PAYMENT_CLAIM_DO以 EIP-3009 authorization 的network + asset + from + nonce取得持久化原子 claim,只有成功取得 claim 的請求才轉送 fact-check-core。核心 handler 回應 <400(本 API 正常為 2xx)才呼叫 settle,成功後回傳PAYMENT-RESPONSE;核心回>=400或 fetch 失敗轉成 502 時直接回錯誤,不會結算付款。 - 同一 authorization 的並發/重放請求回
409 PAYMENT_ALREADY_CLAIMED,不進入 core、 不 settle;PAYMENT-SIGNATURE與X-PAYMENT共用相同 claim。claim 保留到授權validBefore到期後 60 秒才由 alarm 清理,過期授權不能重新進入 core。core/settle 失敗、 結算結果不明或 Worker 中斷時不釋放 claim;重試須用新 nonce 重新簽署,不代表先前一定已扣款。 這是一次性查核嘗試,不是可重用的短期付款租約,也不會快取或重送先前結果。 PAYMENT_CLAIM_DO是必要的 Durable Object binding;未綁定、服務或儲存出錯時回500 PAYMENT_CLAIM_UNAVAILABLE,不會降級成 isolate 內的鎖或放行 core。
付費端點提供寬鬆瀏覽器 CORS:Access-Control-Allow-Origin: *,預檢允許 Content-Type、PAYMENT-SIGNATURE 與 X-PAYMENT,並 expose PAYMENT-REQUIRED、PAYMENT-RESPONSE、X-Request-Id 與 Cache-Control。
以下為 wrangler.jsonc 的正式設定,可由 Worker vars 切換;不是 production code 的 runtime fallback。PAY_TO、X402_NETWORK、X402_PRICE、FACILITATOR_URL 必須明確提供,未設定、空字串或純空白時,付費 GET/POST 回 500 INTERNAL_ERROR,不產生付款要求,也不呼叫 facilitator 或 core;不會自動降級到測試網。
| 變數 | 正式設定 | 說明 |
|---|---|---|
PAY_TO |
0x06818A198832EcEE8Dc8f9B1492C8915921EfEAB |
公開收款錢包 |
X402_NETWORK |
eip155:8453 |
Base mainnet(CAIP-2) |
X402_PRICE |
$0.05 |
每個 HTTP 請求一次付款,0.05 USDC |
FACILITATOR_URL |
https://api.cdp.coinbase.com/platform/v2/x402 |
CDP production facilitator 根網址 |
FACILITATOR_AUTH_TOKEN |
未設定 | 其他 facilitator 可選的固定 Bearer token |
CDP_API_KEY_ID |
未設定 | CDP Secret API Key ID |
CDP_API_KEY_SECRET |
未設定 | CDP Secret API Key Secret |
每一個請求都必須付款;服務不使用 JWT cookie 通行證或跨請求 session。修改 X402_PRICE 時,應同步確認 facilitator 與收款資產的支援,並在對外文件更新實際價格。
本機或測試環境可改用 Base Sepolia:
X402_NETWORK=eip155:84532
FACILITATOR_URL=https://www.x402.org/facilitator使用 Base Sepolia USDC 與公開 faucet 取得測試幣,再依 PAYMENT-REQUIRED 內容付款。公開 x402.org facilitator 目前支援測試網,適合整合測試;測試網付款沒有主網經濟價值。請從 Base 官方文件或可信的 Base Sepolia faucet 取得測試 ETH/USDC,勿把主網私鑰交給 faucet。
公開 https://www.x402.org/facilitator 的 EVM exact scheme 目前僅支援 Base Sepolia 測試網;
wrangler.jsonc 的 Base mainnet 正式設定已改用 Coinbase CDP。請先在 Coinbase Developer Platform
建立一把 Secret API Key,它會同時提供 Key ID 與 Key Secret;不需要另外向 Coinbase 申請
FACILITATOR_AUTH_TOKEN。接著以互動輸入設定 Cloudflare secrets,避免值出現在 shell history:
npx wrangler secret put CDP_API_KEY_ID
npx wrangler secret put CDP_API_KEY_SECRET兩個 CDP 值必須成對設定,且不可與 FACILITATOR_AUTH_TOKEN 混用。後者只適用於明確提供固定
Bearer token 的其他 facilitator。middleware 會透過 Coinbase 官方 SDK 即時產生約兩分鐘有效、
綁定個別 facilitator 路徑的 JWT;FACILITATOR_AUTH_TOKEN 不是拿來保存這種短效 CDP JWT。
x402 middleware 先 verify,再執行 handler;SDK 對 handler 回應 >=400 不呼叫 settle,而是把錯誤回給客戶端。因此 core 回 >=400,或 core fetch 失敗由本 Worker 轉成 502 UPSTREAM_UNAVAILABLE 時,不會結算,客戶端不被扣款。真正的殘餘風險是 core 回 2xx 但本文內容其實是業務錯誤時仍會結算,以及 settle 本身發生網路失敗時需要另外確認付款狀態;x402 沒有內建退款機制。
付費成功時,核心 JSON 與核心回應標頭不改寫。服務自身會維持 X-Request-Id 與 Cache-Control: no-store。
常見錯誤:
| HTTP | 錯誤 | 說明 |
|---|---|---|
| 402 | PAYMENT_REQUIRED 或 facilitator 驗證錯誤 |
依 PAYMENT-REQUIRED 付款後重試 |
| 400 | INVALID_INPUT |
修正 JSON、文字或網址 |
| 413 | PAYLOAD_TOO_LARGE |
縮短 POST 本文 |
| 403 | FORBIDDEN_ORIGIN |
僅適用免費 /api/demo 的 Origin guard |
| 429 | RATE_LIMITED |
僅適用免費 demo 的 IP 限流,依 Retry-After 重試 |
| 502 | UPSTREAM_UNAVAILABLE 或 facilitator 錯誤 |
core 錯誤不 settle;若發生在 settle 階段需另查付款狀態 |
| 500 | INTERNAL_ERROR |
提供 X-Request-Id 協助排查 |
首頁保留查核表單與查核結果呈現;說明區明確標示 /api/fact-check 是每次 0.05 USDC 的 x402 付費 API,並提供免費 /api/demo 入口。表單繼續送往 /api/demo,不會在沒有錢包付款流程的情況下阻斷一般使用者。
vp run dev
vp run check
vp run build
vp testdesign/fact_check_MVP_plan.md 是早期 pipeline 規劃,保留作歷史資料;現行架構與部署設定以本 README 為準。
程式碼採 MIT License。