x402-paid-agent-starter / tree / typescript/src/facilitator.ts ยท raw (this view has old GitHub links rewritten for the mirror; raw is byte-exact)
// 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