x402Fi

Developers

x402 on Robinhood Chain, open.

The no-code gateway covers most sellers. If you run your own server, use the same public facilitator and discovery feed.

Behind the gateway

Paid calls reach your API with two extra headers: X-X402Fi-Secret (from your listing) and X-X402Fi-Payer. Check the secret so the paywall can't be bypassed.

// Your API, behind the x402Fi gateway: reject calls that skip the paywall.
app.use((req, res, next) => {
  if (req.get("x-x402fi-secret") !== process.env.X402FI_SECRET) return res.status(403).end();
  // Optional: who paid for this call
  req.payer = req.get("x-x402fi-payer");
  next();
});

Facilitator

x402 v2, scheme exact, network eip155:4663, asset USDG. x402Fi pays the gas for settlement and never holds funds.

  • POST /api/facilitator/verify
  • POST /api/facilitator/settle
  • GET /api/facilitator/supported
// Self-hosted paywall that uses the x402Fi facilitator (Robinhood Chain, USDG).
const FACILITATOR = "https://x402fi.dev/api/facilitator";
const requirements = {
  scheme: "exact",
  network: "eip155:4663",
  amount: "10000",                      // 0.01 USDG (6 decimals); x402Fi minimum
  asset: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
  payTo: "0xYourWallet",
  maxTimeoutSeconds: 120,
  extra: { name: "Global Dollar", version: "1" },
};

app.get("/rates", async (req, res) => {
  const header = req.get("payment-signature") ?? req.get("x-payment");
  if (!header) {
    const pr = { x402Version: 2, resource: { url: req.url, description: "FX rates", mimeType: "application/json" }, accepts: [requirements] };
    return res.status(402).set("PAYMENT-REQUIRED", Buffer.from(JSON.stringify(pr)).toString("base64")).json(pr);
  }
  const paymentPayload = JSON.parse(Buffer.from(header, "base64").toString());
  const body = JSON.stringify({ paymentPayload, paymentRequirements: requirements });
  const v = await fetch(FACILITATOR + "/verify", { method: "POST", headers: { "content-type": "application/json" }, body }).then(r => r.json());
  if (!v.isValid) return res.status(402).json({ error: v.invalidReason });

  const data = await computeRates();                         // do the work
  const s = await fetch(FACILITATOR + "/settle", { method: "POST", headers: { "content-type": "application/json" }, body }).then(r => r.json());
  if (!s.success) return res.status(402).json({ error: s.errorReason });
  res.set("PAYMENT-RESPONSE", Buffer.from(JSON.stringify(s)).toString("base64")).json(data);
});

Discovery

Every paid endpoint is published in a Bazaar-style feed that agents and indexers can crawl: /api/discovery/resources (JSON), with a readable view at /discovery.

Verified payee

// Name the payee in your 402 so agents can verify you (x402 payee-name extension)
"extensions": { "payee-name": { "info": { "name": "yourco.402api.eth" } } }

// Agents check it with:
import { verifyPayee, viemReader } from "@x402identity/payee";
const verdicts = await verifyPayee(paymentRequired, origin, viemReader(mainnetClient));

Spec: payee-name extension. Records: org.x402.origins and the Robinhood Chain address (coin type 2147488311).

USDG details

Address
0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168
Decimals
6
EIP-712 domain
name "Global Dollar", version "1", chainId 4663
Transfer
transferWithAuthorization (EIP-3009, v/r/s)