v1STABLE

x402

Payment challenges, payload verification, settlement, and receipts.

Payment lifecycle

AgentRanking implements a versioned x402 payment flow around an immutable request and policy snapshot:

  1. Resolve a published offer/resource and active pricing requirement.
  2. Return a bounded payment challenge with network, asset, atomic units, recipient, expiry, and nonce/context binding.
  3. Accept a signed payment payload once and verify its exact request/policy binding.
  4. Observe canonical settlement through the configured facilitator or chain adapter.
  5. Fulfill only after policy requirements pass; persist receipt and reconciliation state.

Amounts are atomic-unit decimal strings and never cross-asset totals. The challenge's network and asset UUIDs must match exactly. Unknown or stale price evidence cannot be silently substituted.

ts
const challenge = await response.json();
const signedPayload = await wallet.signPayment(challenge.data.requirement);
const paid = await fetch(challenge.data.retryUrl, {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "idempotency-key": crypto.randomUUID(),
    "payment-signature": signedPayload,
  },
  body: JSON.stringify(originalRequest),
});

Replay and failure safety

The payload is bound to request ID, requirement version, amount, asset, network, recipient, expiry, and body hash where applicable. Reuse against another resource or changed body is rejected. Concurrent retries converge on one durable request/settlement.

INDETERMINATE means an external payment may have happened without final internal evidence. Do not pay again with a new request. Reconcile the public x402 request resource. Refund and fulfillment failures have separate states; a failed tool result does not erase settlement evidence.

Discovery/readiness indicates protocol support, not that every route is paid or currently healthy.