7Block Labs
Blockchain Technology

ByAUJay

Summary: 402 is finally operationalized. This playbook shows how to ship “proof of payment” HTTP headers that are compatible with emerging x402 v2 flows, verifiable on-chain (USDC/EIP-3009), and provable end-to-end with RFC 9421 message signatures and RFC 9530 content digests—so your platform can meter pay-per-request APIs without new accounts, SDK sprawl, or reconciliation drama. (docs.cdp.coinbase.com)

Developing “Proof of Payment” Headers for HTTP 402 Compliance

Hook — the technical headache you actually feel:

  • Your API gateway can rate-limit and bill monthly, but it can’t meter “$0.004 per inference” for AI agents calling from outside your SSO realm. You tried prepaid keys and webhooks; ops is still manually reconciling, finance wants receipts per response, and a reverse proxy once cached a paid response for free users. Meanwhile product has a Q2 launch date.
  • The missing piece is web‑native payments in the request/response itself, with cryptographic receipts that your auditors and partner APIs can verify without trusting you.

Agitate — the risk if you wait:

  • Missed revenue targets from 20–40% leakage on “trial” keys; partner channels won’t integrate without portable receipts; procurement blocks you because there’s no SLA-backed trace from “402 → paid → 200 OK.” Ship dates slip, the GPT cost line grows, and your margin story deteriorates with every unmetered call.

Solve — 7Block Labs methodology for 402-compliant Proof-of-Payment (PoP) headers We implement payment-as-HTTP, not another payments microservice. The design below uses x402 v2 header conventions, EIP‑3009 for gasless USDC settlement, RFC 9421 for signed responses, and RFC 9530 digests to prove content integrity. This is battle-tested with Coinbase’s x402 facilitator and compatible with neutral routers like P402; it can optionally emit PEAC receipts for independent verification. (docs.cdp.coinbase.com)

  • What “402 compliance” means in practice

    • Use HTTP 402 as the control point: the server returns price and rails in headers, the client retries with a signed payment payload, server verifies/settles, then returns the resource. This is now documented by Coinbase’s x402 docs and live in multiple facilitators. (docs.cdp.coinbase.com)
    • Adopt v2 x402 header names for interop: PAYMENT-REQUIRED (server → client), PAYMENT-SIGNATURE (client → server), and PAYMENT-RESPONSE (server → client on 200). Several ecosystem docs and routers now standardize on these names. (docs.cdp.coinbase.com)
    • Identify networks with CAIP‑2 strings (e.g., eip155:8453 for Base) and tokens with CAIP‑19 to avoid ambiguities across L2s/sidechains. (docs.cdp.coinbase.com)
  • Why EIP‑3009 under the hood

    • Users/agents sign an EIP‑712 “transferWithAuthorization/receiveWithAuthorization” payload; a facilitator submits it and pays gas. No allowances, no “approve + transfer” dance, no user gas. Widely implemented by USDC on major EVM chains; includes on-chain nonce tracking via authorizationState(). (eips.ethereum.org)
    • Security note: when the recipient is a contract, prefer receiveWithAuthorization to prevent mempool front‑running; x402 facilitators can still support both. (eips-wg.github.io)
  • Proof-of-delivery, not just payment

    • Bind the paid content to the response with RFC 9530 Content‑Digest/Repr‑Digest; and sign the 200 OK with RFC 9421 HTTP Message Signatures covering Payment-Response + digest + path/method. Auditors can verify the receipt independent of your stack. (rfc-editor.org)
  • Real‑world performance and ecosystem momentum

    • x402 production docs show CAIP‑2 multi‑network support; community reports sub‑second to ~2s end‑to‑end from 402 to 200 depending on L2 conditions; routers like P402 advertise 99.99% uptime and <100ms internal routing. Treat these as vendor/community indicators; we’ll validate for your SLOs in staging. (docs.cdp.coinbase.com)

Who this is for (and the exact keywords you care about)

  • API Platform Owners, Heads of Monetization, and Staff Engineers running gateways handling >10k RPS with agent traffic:
    • Required keywords: CAIP‑2, CAIP‑19, EIP‑3009, EIP‑712, RFC 9421, RFC 9530, RFC 9651 Structured Fields, Idempotency‑Key (IETF draft), KYT/OFAC screening hooks, p95 end‑to‑end latency, HTTP/2+H3 intermediaries, mTLS, replay protection. (httpwg.org)

The header contract we deploy

  1. 402 response (server → client)
  • Required headers

    • Status: 402 Payment Required (per HTTP semantics). (datatracker.ietf.org)
    • PAYMENT-REQUIRED: Base64URL-encoded JSON (x402 v2) describing accepted payment options, the resource, and anti‑replay data. (docs.cdp.coinbase.com)
    • Content-Type: application/problem+json (RFC 9457) with machine-readable problem details so generic clients can reason about price/expiry/errors. (rfc-editor.org)
  • Example (abbreviated):

HTTP/1.1 402 Payment Required
Content-Type: application/problem+json
PAYMENT-REQUIRED: eyJ4NDAyVmVycyI6MiwgImFjY2VwdHMiOlt7InNjaGVtZSI6ImVpcC0zMDA5IiwgIm5ldHdvcmsiOiJl
aXAxNTU6ODQ1MyIsICJh... (base64url) ...

Decoded PAYMENT-REQUIRED JSON:

{
  "x402Version": 2,
  "resource": "POST /v1/vision/satellite:tile?id=T-918273",
  "accepts": [
    {
      "scheme": "eip-3009",
      "network": "eip155:8453",
      "asset": "eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", 
      "amount": "5000",       // in token base units (e.g., 6 decimals USDC)
      "payTo": "0x7B...B1",
      "validForSeconds": 120
    }
  ],
  "requestDigest": "sha-256=:4Jw...=:",
  "session": "402_sess_f7b2b3d1",
  "facilitator": {
    "verify": "https://facilitator.example.com/verify",
    "settle": "https://facilitator.example.com/settle"
  },
  "extensions": {
    "receipt": "peac", 
    "policyUri": "https://api.example.com/.well-known/peac.txt"
  }
}
  • Notes
    • CAIP‑19 uniquely identifies the USDC contract on Base. (chainagnostic.org)
    • requestDigest is an RFC 9530 digest over selected components of the original request intent (method, path, query, and any signed body fields we require). (rfc-editor.org)
  1. Retry with Proof of Payment (client → server)
  • Required headers
    • PAYMENT-SIGNATURE: Base64URL-encoded JSON with the EIP‑712 authorization (EIP‑3009), correlating to the PAYMENT-REQUIRED fields. (docs.cdp.coinbase.com)
    • Idempotency-Key: a client-generated UUID to make POST/patch idempotent across retries (IETF draft). (ietf.org)

Example payload (decoded):

{
  "scheme": "eip-3009",
  "network": "eip155:8453",
  "asset": "eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "authorization": {
    "from": "0xA1...CE",
    "to": "0x7B...B1",
    "value": "5000",
    "validAfter": 0,
    "validBefore": 1739200000,
    "nonce": "0x9f2c...e1",
    "signature": "0x{r}{s}{v}"
  },
  "bind": {
    "requestDigest": "sha-256=:4Jw...=:",
    "session": "402_sess_f7b2b3d1"
  }
}
  1. 200 OK with cryptographic receipt (server → client)
  • Required headers on success
    • PAYMENT-RESPONSE: Base64URL JSON including txHash or facilitator receipt, final amount, and the same session. (p402.io)
    • Content-Digest/Repr-Digest: integrity of the delivered representation (RFC 9530). (rfc-editor.org)
    • Signature-Input, Signature: RFC 9421 message signatures covering: @method, @path, payment-response, content-digest, date. (rfc-editor.org)
    • Optional: PEAC-Receipt: a compact JWS receipt attesting “who paid what under which policy” (portable verification). (x402.peacprotocol.org)

Example (headers only):

HTTP/1.1 200 OK
Content-Type: application/json
PAYMENT-RESPONSE: eyJ0eEhhc2giOiIweGIxYy4uIiwic2Vzc2lvbiI6IjQwMl9zZXNzX2Y3YiIsImFtb3VudCI6IjUwMDAifQ
Repr-Digest: sha-256=:s8m5o5Hh8n5uC1...=:
Signature-Input: sig1=("@method" "@path" "payment-response" "repr-digest");created=1739189000;keyid="api-gw-key-2026"
Signature: sig1=:kVbC.../==:

Implementation patterns (fast, safe, verifiable)

  • Express middleware (server side)
    • Return 402 with PAYMENT-REQUIRED; on retry, validate PAYMENT-SIGNATURE:
      • Check network and CAIP‑19 match.
      • Recompute requestDigest and session binding.
      • Off-chain verify the EIP‑712 signature; confirm nonce unused via token.authorizationState(); then call facilitator /verify and /settle; or eth_call simulate receiveWithAuthorization and then submit. (eips.ethereum.org)
// Pseudocode: payment middleware
app.post("/v1/vision/satellite:tile", async (req, res, next) => {
  const price = 5000n; // 0.005 USDC, 6 decimals
  const wantsProof = req.headers["payment-signature"];

  if (!wantsProof) {
    return res
      .status(402)
      .set("PAYMENT-REQUIRED", base64url(JSON.stringify(makePaymentRequired(req, price))))
      .type("application/problem+json")
      .send(makeProblemDetails(req, price));
  }

  const proof = decodePaymentSignature(req.headers["payment-signature"]);
  assertCAIP2Network(proof.network, "eip155:8453");
  assertCAIP19Asset(proof.asset, USDC_BASE_CAIP19);
  assertDigestBind(proof.bind.requestDigest, req);

  // Verify EIP-712 auth off-chain
  const okSig = verifyEIP3009TypedData(proof.authorization, USDC_DOMAIN);
  if (!okSig) return res.status(402).send(problem("invalid-signature"));

  // Check nonce unused on-chain
  const used = await usdc.authorizationState(proof.authorization.from, proof.authorization.nonce);
  if (used) return res.status(402).send(problem("nonce-used"));

  // Settle via facilitator (or submit tx directly)
  const vr = await facilitator.verify(proof);
  if (!vr.valid) return res.status(402).send(problem("insufficient-funds"));
  const settle = await facilitator.settle(proof);

  // Produce content and attach receipts/digests/signature
  const body = await renderTile(req.query.id);
  const reprDigest = makeReprDigest(body);
  const payResp = { txHash: settle.txHash, amount: price.toString(), session: proof.bind.session };

  res
    .set("PAYMENT-RESPONSE", base64url(JSON.stringify(payResp)))
    .set("Repr-Digest", reprDigest) // RFC 9530
    .set(makeHttpMessageSignatureHeaders(req, reprDigest, payResp)) // RFC 9421
    .status(200)
    .json(body);
});
  • Client pattern (agent or backend service)

    • Attempt call; on 402, parse PAYMENT-REQUIRED; construct EIP‑3009 typed data; sign; send PAYMENT-SIGNATURE; include Idempotency-Key for POST/patch replays. (docs.cdp.coinbase.com)
  • Caching and intermediaries

    • All 200 OK for paid resources should carry Cache-Control: no-store and no-transform to avoid shared-cache leakage or CDN transformations; also consider Vary: Payment-Signature to segregate cache keys if you intentionally allow caching on private edges. (httpwg.org)
    • Use RFC 9651 Structured Fields when you define any new headers—this maximizes resilience through proxies. If you must ship JSON, base64url-encode it as the ecosystem does today. (httpwg.org)
  • Idempotency and retries

    • Implement the Idempotency-Key draft to make non‑idempotent methods safe under client or network retries (especially important with 402 → pay → 200 flows). (ietf.org)
  • Tamper resistance across hops

    • Sign your success responses (and optionally 402 responses) with RFC 9421 HTTP Message Signatures; cover @method, @path, payment headers, and the content digest. mTLS between API gateway and facilitator further reduces replay risk. (rfc-editor.org)
  • Deterministic nonces (advanced)

    • To correlate authorizations to a specific request without retaining state, derive the EIP‑3009 nonce from a hash of (method, path, query, requestDigest, session) the way several audited systems do for gasless deposits. This improves idempotency and simplifies reconciliation. (openzeppelin.com)

Practical examples with precise, current details

  • Example: Coinbase x402 on Base with CAIP‑2

    • Network identifiers like eip155:8453 are first-class in x402 v2; your Payment‑Required should advertise them, and your buyer should validate that the facilitator settles on that chain. (docs.cdp.coinbase.com)
  • Example: Rust types for EIP‑3009 payloads

    • If you’re in Rust, mirror TransferWithAuthorization exactly to avoid EIP‑712 domain mismatches; community crates already publish the struct and serde derives. (docs.rs)
  • Example: Proof-of-purchase receipts that survive vendor exits

    • PEAC emits a JWS receipt (PEAC‑Receipt) that binds the paid content’s SHA‑256 to a policy snapshot and the settlement reference—portable and independently verifiable. Your 200 OK can include both PAYMENT-RESPONSE and PEAC-Receipt. (x402.peacprotocol.org)
  • Example: ZK/private receipts roadmap

    • If you need “paid, but keep payer/amount private,” emerging stacks generate zk receipts proving a valid payment occurred without disclosing PII; we keep the header contract the same and attach a zk receipt reference in Payment-Response when required. (zkverge.gitbook.io)
  • Example: Confidential facilitators

    • To minimize trust in the facilitator, run its verification inside a TEE (e.g., Oasis ROFL), attest its public key on-chain, and publish an enclave build digest. Now your PAYMENT-RESPONSE can include the TEE attestation reference. (docs.oasis.io)

Security checklist we enforce in delivery

  • Replay and binding
    • Bind the EIP‑3009 nonce to the specific request intent via requestDigest/session; reject mismatches. Use short validity windows (≤120s) in authorizations.
  • Front‑running
    • Prefer receiveWithAuthorization when the payee is a contract; for EOAs, ensure settlement happens server‑side before sending 200 OK. (eips.ethereum.org)
  • Integrity at rest and in transit
    • Sign responses with RFC 9421 and include RFC 9530 digests; enforce TLS 1.2+ and consider mTLS on facilitator links. (rfc-editor.org)
  • Interoperability
    • Use CAIP‑2/CAIP‑19 to identify networks/assets; follow x402 v2 header names; prefer Structured Fields for any custom headers. (docs.cdp.coinbase.com)
  • Caching
    • Cache-Control: no-store, no-transform on paid responses; consider Vary: Payment-Signature if your private edge caches must store results by payer. (httpwg.org)
  • Compliance hooks
    • Add KYT/OFAC hooks in facilitator /verify; emit minimal PII; use receipts (PEAC or equivalent) for audits.

Emerging best practices (Jan 2026)

  • Adopt x402 v2 header names and CAIP‑2 identifiers; treat earlier X‑ headers as legacy. (docs.cdp.coinbase.com)
  • Emit application/problem+json bodies with 402 to standardize client handling (RFC 9457). (rfc-editor.org)
  • Cover PAYMENT-RESPONSE + Repr‑Digest in RFC 9421 signatures; this is what makes a receipt durable across CDNs and logs. (rfc-editor.org)
  • Publish a public /.well-known/… for discovery (pricing, policies, keys); PEAC defines peac.txt and JWS receipts you can verify offline. (x402.peacprotocol.org)
  • Document Idempotency-Key use and TTLs (IETF draft), especially for POST endpoints behind 402. (ietf.org)

What you get with 7Block Labs (technical + business outcomes)

  • Architecture and implementation

    • We deliver a production‑grade 402 PoP flow, instrumented for p95 latency and decision traces. Includes gateway middleware, facilitator integration, on‑chain settlement adapters, RFC 9421 signing, RFC 9530 digests, and optional PEAC receipts.
    • If you need custom rails or cross‑chain expansion, we implement CAIP‑2/19 across chains and add routing policies (e.g., Base primary, fallbacks).
  • Security and audits

    • Formal review of EIP‑712 domains, nonce derivation, and replay boundaries; we can harden facilitators with TEEs (ROFL) and attest them on‑chain.
    • Need a deep dive? Our security audit services cover smart contracts and HTTP signature surfaces as one threat model.
  • Integration and GTM metrics you can commit to

    • Time‑to‑first‑revenue: pilot in 3–6 weeks depending on your gateway (Kong/Envoy/API GW), with 1–2 weeks for x402 facilitator integration and receipts.
    • Latency: indicative measurements across the ecosystem range from sub‑second to ~2s end‑to‑end (402 → settle → 200) depending on L2 load; we size SLOs and retries explicitly in your SOW. (oasis.net)
    • Evidence of adoption: x402 org stats and community reports show tens of millions of transactions processed and multi‑facilitator tooling (e.g., routers, MCP payments). We’ll benchmark your flows against those baselines in staging. (x402.org)
  • Procurement‑friendly deliverables

    • “One‑pager” architecture with RFC references (9421, 9530, 9651), a header matrix, and measurable SLOs.
    • Reconciliation pack: exported ledger of PAYMENT-RESPONSE + txHash + Content‑Digest + signature; finance can sample‑verify without engineering help.
    • Risk controls: KYT hook points, spending caps, and policy-driven routes in facilitator/routers.
  • Where our services plug in


Appendix: Minimal client example (Node, EIP‑3009 on Base/USDC)

import { ethers } from "ethers";
import fetch from "node-fetch";
import base64url from "base64url";

const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
const DOMAIN = { name: "USD Coin", version: "2", chainId: 8453, verifyingContract: USDC_BASE };
const TYPES = {
  EIP712Domain: [
    {name:"name",type:"string"},
    {name:"version",type:"string"},
    {name:"chainId",type:"uint256"},
    {name:"verifyingContract",type:"address"},
  ],
  TransferWithAuthorization: [
    {name:"from",type:"address"},
    {name:"to",type:"address"},
    {name:"value",type:"uint256"},
    {name:"validAfter",type:"uint256"},
    {name:"validBefore",type:"uint256"},
    {name:"nonce",type:"bytes32"},
  ]
};

async function buy(url: string, wallet: ethers.Wallet) {
  // 1) Attempt
  const r1 = await fetch(url, { method: "POST", body: JSON.stringify({id:"T-918273"}) });
  if (r1.status !== 402) throw new Error(`Expected 402, got ${r1.status}`);
  const pr = JSON.parse(base64url.decode(r1.headers.get("payment-required")!)); // x402 v2

  // 2) Build EIP-3009 auth
  const msg = {
    from: wallet.address,
    to: pr.accepts[0].payTo,
    value: pr.accepts[0].amount,
    validAfter: 0,
    validBefore: Math.floor(Date.now()/1000)+120,
    nonce: ethers.hexlify(ethers.randomBytes(32))
  };
  const sig = await wallet._signTypedData(DOMAIN, { TransferWithAuthorization: TYPES.TransferWithAuthorization }, msg);

  const proof = {
    scheme: "eip-3009",
    network: pr.accepts[0].network,
    asset: pr.accepts[0].asset,
    authorization: { ...msg, signature: sig },
    bind: { requestDigest: pr.requestDigest, session: pr.session }
  };

  // 3) Retry with PAYMENT-SIGNATURE + Idempotency-Key
  const r2 = await fetch(url, {
    method: "POST",
    headers: {
      "Payment-Signature": base64url.encode(JSON.stringify(proof)),
      "Idempotency-Key": crypto.randomUUID(),
      "Content-Type": "application/json"
    },
    body: JSON.stringify({id:"T-918273"})
  });

  if (r2.status !== 200) throw new Error(`Payment failed: ${await r2.text()}`);
  const payResp = JSON.parse(base64url.decode(r2.headers.get("payment-response")!));
  console.log("txHash", payResp.txHash, "digest", r2.headers.get("repr-digest"));
}

References for the standards and flows used above: HTTP 402 semantics; x402 v2 headers and CAIP‑2; EIP‑3009 authorization types and security considerations; RFC 9421 HTTP Message Signatures; RFC 9530 digests; RFC 9651 Structured Fields; Idempotency‑Key IETF draft. (datatracker.ietf.org)


Prove — GTM metrics we put on a roadmap

  • Pilot in 3–6 weeks; “first paid 200 OK” in <10 business days once your facilitator credentials are ready.
  • Baseline performance: ecosystem references show sub‑1s claims and up to ~2s E2E with L2 congestion; we tune retry backoffs and validity windows to your SLOs. (oasis.net)
  • Interop coverage: CAIP‑2 networks (Base, Ethereum, Solana where applicable), EIP‑3009 on USDC, RFC‑compliant signatures/digests; routers such as P402 if you need policy/routing and Discovery (“Bazaar”) metadata. (docs.cdp.coinbase.com)
  • Receipts: optional PEAC JWS receipts enable offline verification and policy binding for procurement/legal reviews. (x402.peacprotocol.org)

7Block Labs | How we engage

CTA — if this is you, we should talk this week

  • If you own the API Gateway or Monetization stack for a Base‑first AI SaaS and you’re targeting “pay‑per‑inference” in Q2 2026 with p95 <1.5s, we’ll spend 45 minutes walking your team through a header‑level design (PAYMENT‑REQUIRED/SIGNATURE/RESPONSE), an RFC 9421 signature set that your auditors can verify, and a staged rollout on your gateway—then deliver a two‑week pilot that returns real 200 OKs with verifiable receipts. Reply with your current gateway (Kong/Envoy/CloudFront) and target chain; we’ll bring a tailored plan and a working PoP demo that hits your SLOs and your CFO’s reconciliation needs.

Like what you're reading? Let's build together.

Get a free 30-minute consultation with our engineering team.

Related Posts

7BlockLabs

Full-stack blockchain product studio: DeFi, dApps, audits, integrations.

7Block Labs is a trading name of JAYANTH TECHNOLOGIES LIMITED.

Registered in England and Wales (Company No. 16589283).

Registered Office address: Office 13536, 182-184 High Street North, East Ham, London, E6 2JA.

© 2026 7BlockLabs. All rights reserved.