// Default facilitator: HTTP calls to POST <url>/verify and POST <url>/settle (x402 v1 body).
import type { Facilitator, PaymentPayload, PaymentRequirements, SettleResult, VerifyResult } from './x402.js';
export const DEFAULT_FACILITATOR_URL = 'https://x402.org/facilitator';
type FetchFn = (url: string, init: { method: string; headers: Record<string, string>; body: string }) => Promise<{ ok: boolean; status: number; json(): Promise<unknown> }>;
export function httpFacilitator(url: string = DEFAULT_FACILITATOR_URL, fetchImpl?: FetchFn, headers: Record<string, string> = {}): Facilitator {
const base = url.replace(/\/+$/, '');
const f: FetchFn = fetchImpl ?? ((u, i) => (globalThis.fetch as unknown as FetchFn)(u, i));
async function post<T>(path: string, paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements): Promise<T> {
const res = await f(`${base}/${path}`, {
method: 'POST',
headers: { 'content-type': 'application/json', ...headers },
body: JSON.stringify({ x402Version: 1, paymentPayload, paymentRequirements }),
});
const body = (await res.json().catch(() => ({}))) as T;
if (!res.ok && typeof body !== 'object') throw new Error(`facilitator ${path} answered HTTP ${res.status}`);
return body;
}
return {
verify: (p, r) => post<VerifyResult>('verify', p, r),
settle: (p, r) => post<SettleResult>('settle', p, r),
};
}
agentgate-source: code mirror on Cloudflare Pages. All repos