Proposed changelog for x402 v2 spec + reference sdk
Proposed x402 v2 Protocol & SDK Refactor
This PR introduces CHANGELOG-v2.md, a draft outlining the proposed changes in x402 to be captured in v2 of the specification, HTTP transport, SDK, and middleware layers.
Purpose
The changelog is intended to:
- Serve as the canonical proposal for x402 v2
- Align contributors and reviewers on the core spec updates
- Act as the discussion base for ideas and implemention of v2 across x402 and all community packages
Feedback from the community is welcome, please comment with feedback on the proposed items, or create PRs into this PR with proposed changes that are not captured.
Note: The SDK refactor to support v2 will maintain full backward compatibility with v1 implementations.
Next Steps
Please review and leave feedback. This changelog is the proposed spec and implementation baseline for x402 v2. No implementation changes are included in this PR.
Once agreed upon, this PR will be merged into a v2 branch, and development to update the x402 monorepo will begin.
We are seeking contributors to aid in the implementation of v2. Please comment if you are willing and able.
Huge thanks to @CarsonRoscoe for consolidating all the feedback we've received and ideas the team has had.
🟡 Heimdall Review Status
| Requirement | Status | More Info | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Reviews |
🟡
0/1
|
Denominator calculation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| x402 | Preview | Comment | Oct 23, 2025 6:13am |
Can you guys add flutter firebase integration.... not trying to build some custom web view bridge
Review Error for kdenhartog @ 2025-10-11 11:56:32 UTC User must have write permissions to review
exciting!
some thoughts from me and some folks at vercel:
overall looks good
signed identifier: it’s not clear to me where the expiry time comes from. is it returned by the server after a previous payment for the resource (for example, as part of a prior payload)?
- does the server also specify the cryptographic curve being used?
support for multiple facilitators in the middleware is needed (for redundancy), but it would be helpful to clarify how routing to different facilitators based on the network is intended to work
on the protocol / sdk side something that still seems missing is charging based on some metered value that is only known after the request has been processed (ie charge per token)
- is this something that just requires a new scheme? or is it a protocol level concern?
Thanks for the feedback!
Signed Identifier expiry time: We'd have a default convention here (likely of 60s), servers would have the ability to reject identifiers that have a very long expiry to prevent re-use. (Expiry time is included in the identifier payload, via signature recovery you can confirm the signature includes the timestamp presented)
- does the server also specify the cryptographic curve being used?
The client would use whichever curve they have available (we're trying to keep the number of keys a client needs to manage as minimal as possible). Curve recovery across multiple curves is far easier than managing multiple keys.
- on the protocol / sdk side something that still seems missing is charging based on some metered value that is only known after the request has been processed (ie charge per token)
Yes! v2 changelog is about breaking structural changes we want to make, this usecase will be addressed soon with a spec called upto
Thanks for the thorough feedback!
There’s quite a bit of additional complexity that’s being introduced here with this proposal. Here’s some key considerations I’ve spotted so far:
- The facilitator opens a control point on the protocol that will be captured from a regulatory standpoint and goes against a core principle of protocol design in IETF. This will lead to a debanking problem and offers the payment requestor an outsized control in the negotiation process of which payment rail should be used. For example, if the endpoint only supports cloudflare the US government will be able to use OFAC sanctions to capture the payment rail method and prevent acceptance of payments from highly sanctioned regions.
Facilitators are a fully optional component of x402 and always will be. The goal of x402 is to cast as wide a net as possible and be the Schelling point for internet native payments. This means that both crypto and fiat will need to be supported, and will need to live on equal footing where clients and servers can choose what they mutually agree to use. Not all facilitators will be able to operate all networks / schemes, I just don't think its realistic to attempt to enforce at the protocol level.
For example, if the endpoint only supports cloudflare the US government will be able to use OFAC sanctions to capture the payment rail method and prevent acceptance of payments from highly sanctioned regions.
Ultimately that is the decision of the entity that is monetizing the endpoint. Any endpoint that uses x402 can adopt 1 or many ways to accept payment, each will have tradoffs.
- You’ll need authn capabilities built in for different types of payment rails here which makes this a bit clunky. Some rails such as crypto will inherently have authentication built in, where as others will not and will require additional definitions.
For example, if using “cloudflare” / ACH how do you authenticate to the facilitator that you own the identifier that the payment should be made from? I’d suggest relying on HTTP Signatures for this, but you’ll probably need each payment rail to define this within its own method.
Fully agree with the point. For some payment networks like ach there may need to be a linking step that occurs before a payment can be made. For others like stablecoin payments / crypto there isn't. IMO competition between payment networks to provide the best UX should be encouraged. Ultimately clients and servers will dictate what is used and what isn't.
cloudflare's current pay-to-crawl mechanism leverages HTTP Signatures. Their proposed network will be up soon, I'd imagine they would continue with the pattern.
- “Cloudflare” and “ACH” are not sufficiently defined payment rails. Also, you’ll need to establish a registry for these. I’d suggest defining an IANA registry for this and a process of how to register new ones to keep it sufficiently clear how a new party can define and register a new method of payment.
Yes. Cloudflare is in the process of writing up their proposal, ach is purely a theoretical. We included them as examples of constant values being used when there isn't a clear way to represent the underlying network with CAIP-10.
- The privacy implications of this will be heavily reliant on the method used. For example, in crypto rails you’ll hit issue #406 where as with cloudflare or ACH you’ll leak this information only to the facilitator.
+1. Would love a proposal on privacy. Broadly crypto rails trade off openness for privacy, its an industry wide issue we should address. Being pragmatic, I think its a problem to solve but not a blocker.
- There will be settlement time tradeoffs depending on the payment rail used. E.g. ACH typically operates on a same day schedule unless risk checks are needed. Crypto will depend on the underlying network used - e.g. BTC is roughly 60 minutes where as an L2 specifically designed for this may operate with instant finality
+1. See comment above on choice and tradeoffs. Competition on a level playing field and consumer choice.
- How can the client communicate that it doesn’t support a particular set of payment rails and propose an alternative via a header in a repeat request?
As of right now it can't. I would love a suggestion on a mechanism, but as of now I haven't been able to come up with one that doesn't inherently require new infra for the server to be provisioned (ex: a wallet), meaning that the server wouldn't be able to accept in the request flow regardless. The alt would be a way to signal desire to pay in a currency, but that feels a bit too meta at this point and not fleshed out enough for a v2. Perhaps in future.
Also, is there a call where we can discuss these further? One thing I notice we're doing here is falling back into the anti-pattern that every other e-commerce protocol has fallen into so far. If we define proprietary methods of payment, we devolve the standard into a zero sum game like what happened with Web Payments API. Game theory suggests that an open method where we can adversarially interop here will actually help everyone through a rising tides floats all boats strategy. What I mean by this is that if we establish the proprietary method 1 and proprietary method 2 approach then method 1 captures some small portion of value relative to their market share and method 2 does similar. Where as, if you design the protocol such that people are forced to adversarially interop it incentivizes everyone to stake their market shares to grow the market as a whole creating a win-win ecosystem for everyone. In that way, the economic output is greater for everyone (aka every operator make more revenue) even if the independent market share of a single entity might be smaller. This is a design principle we need to align on here. Otherwise we'll just end up back in the same place web payments did (aka not adopted heavily).
Where as, if you design the protocol such that people are forced to adversarially interop it incentivizes everyone to stake their market shares to grow the market as a whole creating a win-win ecosystem for everyone. Agreed, which is why x402 aims to be a neutral standard that allows multiple mechanisms for settlement to compete.
call Yes! We intend to have an open developers call in the coming weeks before we finalize v2. Stay tuned here or https://x.com/programmer for details.
Count me in — I’d love to help with the v2 implementation. I have been working on https://github.com/coinbase/x402/pull/454, https://github.com/coinbase/x402/issues/439
Side note, we should move this conversation to a separate discussion I think.
@erikreppel-cb the reason payment protocols of the past have failed to get adoption and the Web has reverted back to using proprietary SaaS providers is because we've taken these same design choices previously. This happens because everyone attempts to turn the interface into a proprietary way that they can capture value without having to risk losing their customers. A good standard needs to force people to stake their user base to try and capture others in a game of adversarial interop. This is done by removing as many optionality points and keeping only the ones you think you'll need. By doing this you maximize the number of connections under metcalf's law by forcing all the implementations client/server side to interop. If you want another example of where this failed recently then look no further than Decentralized Identifiers. That spec made did methods and led to DID compliant implemtnations being able to interop with each other. Only the identifiers were interoperated and everything else was optional so the only place that's seen large scale deployment is AT Protocol and the one method it supports (did:plc). It did this via vertical integration.
I'm not sure how familiar you are with the Web Payments API either, but essentially it made the same design choices as this is going towards. What ended up happening was that Google, Apple, Samsung, and Stripe all tried to standardize on it but each saw the protocol as an opportunity to turn the interface into a method of capturing e-commerce transactions for their respective networks through their own distribution channels. By doing this, they essentially established 4 separate networks which don't all interoperate. For example, I can't use the Google Pay button on an iPhone and vis-a-versa. This design choice ends up reverting the protocol back to isolated networks which create metcalf's law networks for each method rather than a single interoperable network of clients and servers. This typically means a long tail distribution forms around methods and the largest adopter server side then dominates the protocol outcomes. E.g. If Cloudflare steps in and puts their own method in and only cloudflare supports it, then Stripe does the same, etc then it basically kicks the complexity out to the client to decide which to support. The clients will naturally support a limited number of options and will focus their efforts towards the top 2 or 3 to keep maintainability down while covering a good enough distribution. Each method will then grow independently and not contribute to the overall growth of the network. Instead, it will only contribute to the adoption of the interface which is relatively simple to replace.
Over time then, this solidifies the growth towards the limited number of server side methods that get adopted which basically means that cloudflare, stripe, and probably one or two other large tech providers become the primary adopters of this and capture the value through their proprietary methods, but they don't actually acquire new customers from the network.
If that's the goal of this protocol then I suppose it's not really what I was expecting. I was thinking we were trying to grow the overall payments network, not just the data model and interaction patterns.
+1. Would love a proposal on privacy. Broadly crypto rails trade off openness for privacy, its an industry wide issue we should address. Being pragmatic, I think its a problem to solve but not a blocker.
I'll just say now, you won't see any browser adopt this until this is solved. You'll also likely introduce a hornet's nest of GDPR violations which will make people stop touching x402 with crypto with a 10 foot pole once EU regulators catch wind of this stuff and start handing out violations. At that point, crypto get's tossed out the window as a method and this becomes a forcing function that pushes us towards the largest proprietary method wins outcome that I described above.
Hey this is great, excited to see x402 evolve so rapidly. Happy to help where needed as well, I've been working on https://github.com/coinbase/x402/pull/426 for a while so became quite familiar with the codebase.
One area I'd love to see v2 explore further is the stateless nature of facilitators. In the scheme we are building (see PR above) we rely on a stateful facilitator to store signed IOUs. This mainly benefits sellers, they could maintain that state themselves and use a stateless facilitator instead, but in practice we think most would prefer not to.
The way we've built the scheme and the facilitator allows for a "facilitator migration" if that was required. I realize this approach is probably a bit removed from the original intention behind facilitators but IMO there are certain use cases where limited statefulness is worth considering/supporting (our deferred scheme proposal is one, but another one could be payments "over time", where a service is continuously provided and the seller accrues payment over time). It would be nice if v2 to defined some guidelines for this type of designs (what is allowed, what not, under what circumstances it makes sense, etc).
Hey this is great, excited to see x402 evolve so rapidly. Happy to help where needed as well, I've been working on #426 for a while so became quite familiar with the codebase.
One area I'd love to see v2 explore further is the stateless nature of facilitators. In the scheme we are building (see PR above) we rely on a stateful facilitator to store signed IOUs. This mainly benefits sellers, they could maintain that state themselves and use a stateless facilitator instead, but in practice we think most would prefer not to. The way we've built the scheme and the facilitator allows for a "facilitator migration" if that was required. I realize this approach is probably a bit removed from the original intention behind facilitators but IMO there are certain use cases where limited statefulness is worth considering/supporting (our
deferredscheme proposal is one, but another one could be payments "over time", where a service is continuously provided and the seller accrues payment over time). It would be nice if v2 to defined some guidelines for this type of designs (what is allowed, what not, under what circumstances it makes sense, etc).
@tmigone So my take is the x402 spec should only align the interface to the facilitator (the API spec), but not the implementation of the facilitator - i.e if a particular facilitator builder finds value in adding state, they're free to
That being said I think we should try our best to keep schemes stateless if possible, because portability is hard (solving portability hard). I owe you guys a review, I have started it just takes a while with a +22k PR 😅
Hey folks, we're going to have a developer call on wednesday! RSVP here: https://luma.com/61teg2fe
although it might be a bit early for me to join deeper discussions — since our work is still in progress — i’d like to share some of our ideas in advance, hoping they might be of value for the working group’s consideration.
we’re designing a “authorize first, settle later” instant payment protocol. it’s somewhat inspired by concepts like magis spend and gnosis pay — enabling a payer to sign an authorization, while the paymaster can verify it and deliver the service first, then execute settlement afterward. we’re applying this model to agent payments, aiming to improve the payment experience for both payer and payee.
specifically, we hope the protocol can support: 1. client (payer) signs a payment authorization that can later be submitted on-chain for deduction. 2. server (payee) verifies the authorization to ensure it can be settled later; if valid, it proceeds to provide the service.
this payment model requires extending x402’s support for custom payment payloads and server-side validation logic.
since we’re still building, we’re not yet clear on how extensible the new version of x402 will be — but we wanted to put this idea forward early. thanks a lot for your attention!
related material: 1. https://www.fluxapay.xyz/protocol
Having read through the whitepaper and now this thread I have some thoughts.
Proposal A: x402 should returns a transaction signing payload rather than parameters for payment.
The advantage of this schema is that the responding client can immediately sign a payload and respond. The consuming (x402) server will then submit the signed transaction using their own RPC.
Additionally this gives the server a notion of transaction finality and control over transaction finality. Responses will be simplified terse.
The disadvantages of this design is a malicious x402 server could serve an opaque wallet draining transaction. To guard against this outcome, clients could simulate transactions and determine the balance changes as a result and choose not to sign on some heuristic like maximum payment amount.
Proposal B: x402 design returns parameters (as it already does) and the client responds with a signed transaction in the request.
The advantage of this design is the signing is human readable. The client can apply heuristics to the payment.
Additionally it comes with the advantages of proposal A regarding payment finality.
Review Error for iBoywonder @ 2025-10-29 02:35:54 UTC User must have write permissions to review
Review Error for wongzigii @ 2025-11-05 10:41:56 UTC User must have write permissions to review