x402 has two protocol versions. Version 2 is preferred for new integrations. Faremeter supports both versions simultaneously, and the middleware can serve v1 and v2 clients at the same time.
At a glance
Version 1
In v1, the server returns payment requirements in the 402 response body as JSON:
The client sends its payment proof in the X-PAYMENT header:
The decoded payload contains:
Version 2
v2 uses dedicated HTTP headers for the payment protocol, separating payment data from the response body.
The server returns requirements in both the response body and the PAYMENT-REQUIRED header. On successful payment, it includes a PAYMENT-RESPONSE header with the settlement result.
The client sends its payment proof in the PAYMENT-SIGNATURE header. The v2 payload includes the accepted requirement the client chose, plus resource information:
Including the accepted requirement in the payload lets the facilitator verify that the client is paying for the correct requirement without relying on the server to re-send it.
Configuring version support
The middleware uses resolveSupportedVersions() to determine which protocol versions to serve. By default, v1 is enabled and v2 is disabled.
Pass this to createMiddleware or handleMiddlewareRequest:
With createMiddleware (Express)
With handleMiddlewareRequest
Migrating from v1 to v2
- Enable both versions during the transition so existing v1 clients continue to work:
- Update clients to use the latest
@faremeter/rides or @faremeter/fetch, which automatically negotiate the highest supported version.
- Disable v1 once all clients have migrated:
Version adapters
If you are running your own facilitator and need to convert between v1 and v2 formats, use the adapter functions from @faremeter/types/x402-adapters:
adaptSettleResponseV2ToV1Legacy is deprecated. Use adaptSettleResponseV2ToV1 for spec-compliant v1 output.
Further reading